package hotel.meituan.oversea.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.CommonUrlConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.constant.enums.CommonEnums;
import hotel.base.oversea.constant.enums.MessageEnums;
import hotel.base.oversea.constant.enums.MtGoodsEnums;
import hotel.base.oversea.constant.enums.MtHotelEnums;
import hotel.base.oversea.constant.quartz.UrlSwitchsEnums;
import hotel.base.oversea.dto.meituan.MtHotelOrderBookingDto;
import hotel.base.oversea.service.impl.BaseServiceImpl;
import hotel.base.oversea.utils.*;
import hotel.base.oversea.vo.meituan.request.order.MtHotelOrderCheckParamVo;
import hotel.base.oversea.vo.meituan.response.order.MtHotelOrderCheckPricesVo;
import hotel.base.oversea.vo.meituan.response.order.MtHotelOrderCheckVo;
import hotel.meituan.oversea.api.dto.MtHotelOrderBookingDealingDto;
import hotel.meituan.oversea.api.entity.*;
import hotel.meituan.oversea.api.vo.down.request.order.*;
import hotel.meituan.oversea.api.vo.switchs.OperateDltOrderVo;
import hotel.meituan.oversea.api.vo.up.response.order.*;
import hotel.meituan.oversea.biz.config.service.RedisService;
import hotel.meituan.oversea.biz.mapper.*;
import hotel.meituan.oversea.biz.service.MtHotelOrderDealService;
import hotel.meituan.oversea.biz.service.MtHotelOrderDealSplitService;
import hotel.meituan.oversea.biz.service.MtHotelOrderService;
import hotel.meituan.oversea.biz.task.MeituanSaveApiLogTask;
import hotel.meituan.oversea.biz.utils.MtUtils;
import hotel.meituan.oversea.biz.utils.RestTemplateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class MtHotelOrderServiceImpl extends BaseServiceImpl implements MtHotelOrderService {
    @Autowired
    private MtHotelOrderBookingMapper mtHotelOrderBookingMapper;
    @Autowired
    private MtHotelOrderBookingProductsMapper mtHotelOrderBookingProductsMapper;
    @Autowired
    private MtHotelDetailMapper mtHotelDetailMapper;
    @Autowired
    private MtHotelOrderDealSplitService mtHotelOrderDealSplitService;
    @Autowired
    private MtHotelOrderDealService mtHotelOrderDealService;
    @Autowired
    private MtHotelOrderCheckHistoryMapper mtHotelOrderCheckMapper;
    @Autowired
    private MtHotelOrderService mtHotelOrderService;
    @Autowired
    private MtHotelOrderStateHistoryMapper mtHotelOrderStateHistoryMapper;
    @Autowired
    private MtHotelOrderCheckPricesHistoryMapper mtHotelOrderCheckPricesMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    MeituanSaveApiLogTask meituanSaveApiLogTask;


    /**
     *
     * 订单校验
     *
     * {
     *     "code": 0,
     *     "message": "成功",
     *     "partnerId": 666,
     *     "result": {
     *         "code":0,
     *         "desc":"校验成功",
     *         "priceModels": [
     *             {
     *                 "date": "2016-10-01",
     *                 "salePrice": 20000,
     *                 "subPrice": 500,
     *                 "subRatio": 400,
     *                 "dayType": 0
     *             }
     *         ],
     *         "remainRoomNum":1
     *     }
     * }
     * {"code":0,"message":"成功","partnerId":3,"result":{"code":8,"desc":"价格发生变化!","priceModels":[{"date":"2020-06-10","salePrice":13800,"subPrice":690,"subRatio":500,"dayType":0},{"date":"2020-06-11","salePrice":13800,"subPrice":690,"subRatio":500,"dayType":0}],"remainRoomNum":999}}
     * {"code":0,"message":"成功","partnerId":3,"result":{"code":0,"priceModels":[{"date":"2020-06-10","salePrice":13800,"subPrice":690,"subRatio":500,"dayType":0}],"remainRoomNum":999}}
     * @param mtHotelOrderParamVo
     * @return
     */
    @Override
    public Result<Object> orderCheckApi(MtHotelOrderCheckParamVo mtHotelOrderParamVo) {
        String s = JSONObject.toJSONString(mtHotelOrderParamVo);

        Long hotelId = mtHotelOrderParamVo.getHotelId();
        int goodsId = mtHotelOrderParamVo.getGoodsId();
        String checkinDate = mtHotelOrderParamVo.getCheckinDate();
        String checkoutDate = mtHotelOrderParamVo.getCheckoutDate();
        int roomNum = mtHotelOrderParamVo.getRoomNum();
        int totalPrice = mtHotelOrderParamVo.getTotalPrice();
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("hotelId",hotelId);
        dataMap.put("goodsId",goodsId);
        dataMap.put("checkinDate",checkinDate);
        dataMap.put("checkoutDate",checkoutDate);
        dataMap.put("roomNum",roomNum);
        dataMap.put("totalPrice",totalPrice);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_CHECK.getMethod(),meituanSaveApiLogTask);
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))){
            String result = responseJson.getString("result");
            if(null != result){
                MtHotelOrderCheckVo mtHotelOrderCheckVo = null;
                try {
                    mtHotelOrderCheckVo = JSON.parseObject(result, MtHotelOrderCheckVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(null == mtHotelOrderCheckVo){
                    log.error("////////////////MTAPIERROR///////////////////酒店订单校验接口数据异常 result parse vo error：{}",result);
                    return new Result<>("parse error", CommonConstants.PARSE_ERROR);
                }else{
                    //再一层code判断
                    if(0==mtHotelOrderCheckVo.getCode()){
                        //不要多套一层code
                        Map map = new HashMap();
                        map.put("priceModels",mtHotelOrderCheckVo.getPriceModels());
                        map.put("remainRoomNum",mtHotelOrderCheckVo.getRemainRoomNum());
                        //保存日志数据，trycatch不影响接口流程
                        saveOrderCheckHistory(dataMap,mtHotelOrderCheckVo);
                        return new Result<>(mtHotelOrderCheckVo);
                    }else{
                        //{"code":0,"message":"成功","partnerId":12734,"result":{"code":3,"desc":"产品goodsId:59943不可预订, goodsStatus:0","priceModels":[]}}
                        //{"code":3,"desc":"产品goodsId:17387288不可预订, goodsStatus:0","priceModels":[]}
                        saveOrderCheckHistory(dataMap,mtHotelOrderCheckVo);
                        return new Result<>(mtHotelOrderCheckVo);
                    }
                }
            }else{
                return new Result<>("error", CommonConstants.REQUEST_ERROR);
            }
        }else{
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     *   保存订单校验数据日志:请求参数数据+返回参数数据  表1 和 表2
     * @param responseVo
     */
    public void saveOrderCheckHistory(Map<String,Object> requestBusinessMap,MtHotelOrderCheckVo responseVo){
        if(null != requestBusinessMap && requestBusinessMap.size()>0){
            //单天订单才需要更新房态缓存
            if(DateUtil.dateDiff(requestBusinessMap.get("checkinDate").toString(),"day",requestBusinessMap.get("checkoutDate").toString(),"yyyy-MM-dd")==1){
                if(responseVo.getCode()==3 || responseVo.getCode()==6){
                    //3 房态为不可预订   6 库存不足
                }
            }


            MtHotelOrderCheckHistory checkEntity = new MtHotelOrderCheckHistory();
            String mtCheckId = UUID.randomUUID().toString();
            checkEntity.setId(mtCheckId);
            checkEntity.setMtHotelId(requestBusinessMap.get("hotelId").toString());
            checkEntity.setMtGoodsId(requestBusinessMap.get("goodsId").toString());
            checkEntity.setMtCheckinDate(requestBusinessMap.get("checkinDate").toString());
            checkEntity.setMtCheckoutDate(requestBusinessMap.get("checkoutDate").toString());
            checkEntity.setMtRoomNum((Integer) requestBusinessMap.get("roomNum"));
            checkEntity.setMtTotalPrice((Integer)requestBusinessMap.get("totalPrice"));
            checkEntity.setState(CommonEnums.STATE_NORMAL.getCode());
            checkEntity.setRemark(JSON.toJSONString(responseVo)+" | "+ JSON.toJSONString(requestBusinessMap));
            checkEntity.setCreateTime(new Date());
            checkEntity.setModifyTime(checkEntity.getCreateTime());
            List<MtHotelOrderCheckPricesHistory> priEntityList = new ArrayList<>();
            if(null != responseVo){
                checkEntity.setMtRemainRoomNum(responseVo.getRemainRoomNum());
                List<MtHotelOrderCheckPricesVo> prices = responseVo.getPriceModels();
                if(null != prices && prices.size()>0) {
                    for (MtHotelOrderCheckPricesVo price : prices) {
                        MtHotelOrderCheckPricesHistory priceEntity = new MtHotelOrderCheckPricesHistory();
                        priceEntity.setId(UUID.randomUUID().toString());
                        priceEntity.setMtHotelOrderCheckId(mtCheckId);
                        priceEntity.setMtHotelId(requestBusinessMap.get("hotelId").toString());
                        priceEntity.setMtGoodsId(requestBusinessMap.get("goodsId").toString());
                        priceEntity.setMtDate(price.getDate());
                        priceEntity.setMtSalePrice(price.getSalePrice());
                        priceEntity.setMtSubPrice(price.getSubPrice());
                        priceEntity.setMtSubRatio(price.getSubRatio());
                        priceEntity.setMtDayType(price.getDayType());
                        priceEntity.setState(CommonEnums.STATE_NORMAL.getCode());
                        priceEntity.setCreateTime(new Date());
                        priceEntity.setModifyTime(new Date());
                        priEntityList.add(priceEntity);

                    }
                }
            }
            /**
             * 日志不删除重复
             */
            if(null != priEntityList && priEntityList.size()>0){
                mtHotelOrderCheckPricesMapper.insertList(priEntityList);
            }
            mtHotelOrderCheckMapper.insert(checkEntity);
        }
    }

    public static void main(String[] args) {
        /*System.out.printf("=="+MtHotelEnums.orderStateEnum.getDesc(22));*/


        Long dif = DateUtil.dateDiff("2020-09-16 20:06:59","min",DateUtil.getCurrTime(),"yyyy-MM-dd HH:mm:ss");
        System.out.printf("=="+dif);
    }
    /**
     * 保存预约下单信息
     * @param mtHotelOrderBookingParamVo
     * @return
     */
    @Override
    public MtHotelOrderBooking saveRequsetOrderBooking(MtHotelOrderBookingVo meiTuanHotelOrderBookingVo, MtHotelOrderBookingParamVo mtHotelOrderBookingParamVo, Integer orderState, Integer state, String distributorOrderIdIsHhbOrderId_index, String swOrderId, String masterOrderId, Integer split,Integer swTotalPrice) {
        String requstDesc  = null;
        String mtOrderId = null;
        if(null != meiTuanHotelOrderBookingVo){
            mtOrderId = meiTuanHotelOrderBookingVo.getMtOrderId();
            requstDesc = meiTuanHotelOrderBookingVo.getDesc();//下单失败或成功
        }
        Integer minInit = (Integer) redisTemplate.opsForValue().get("mt_reminder_count_init");
        if(null == minInit){
            minInit = 3;
        }

        MtHotelOrderCheckVo mtHotelOrderCheckVo = mtHotelOrderBookingParamVo.getMtHotelOrderCheckVo();
        if(null== mtHotelOrderCheckVo){
            mtHotelOrderCheckVo = new MtHotelOrderCheckVo();
        }
        MtHotelOrderBooking orderBooking = new MtHotelOrderBooking();
        orderBooking.setId(UUID.randomUUID().toString())
                .setMtHotelId(mtHotelOrderBookingParamVo.getHotelId())
                .setMtOrderState(orderState)
                .setMtOrderId(mtOrderId)
                .setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index)
                .setSwOrderId(swOrderId)
                .setSplitSuccessCount(0)
                .setCancelSuccessCount(0)
                .setCancelFailedCount(0)
                .setMasterOrderId(masterOrderId)
                .setSplit(split)
                .setMtGoodsId(mtHotelOrderBookingParamVo.getGoodsId())
                .setMtPersonNames(mtHotelOrderBookingParamVo.getPersonNames())
                .setMtContactName(mtHotelOrderBookingParamVo.getContactName())
                .setMtContactPhone(mtHotelOrderBookingParamVo.getContactPhone())
                .setMtArriveDate(mtHotelOrderBookingParamVo.getArriveDate())
                .setMtCheckinDate(mtHotelOrderBookingParamVo.getCheckinDate())
                .setMtCheckoutDate(mtHotelOrderBookingParamVo.getCheckoutDate())
                .setMtRoomNum(mtHotelOrderBookingParamVo.getRoomNum())
                .setSwTotalPrice(swTotalPrice)
                .setMtTotalPrice(mtHotelOrderBookingParamVo.getTotalPrice())
                .setMtSettlePrice(mtHotelOrderBookingParamVo.getSettlePrice())
                .setMtInventoryNumber(mtHotelOrderCheckVo.getRemainRoomNum())
                .setMtComment(mtHotelOrderBookingParamVo.getComment())
                .setMtPersonIdentities(mtHotelOrderBookingParamVo.getPersonIdentities())
                .setMtNeedInvoice(mtHotelOrderBookingParamVo.getNeedInvoice())
                .setIsReminderCount(0)//初始化 催单次数为0
                .setIsReminderWaitTime(minInit);//初始化 催单(提醒订单还未接单)时间  2分钟
        if(!ObjectUtils.isEmpty(split)){
            orderBooking.setSplit(split);
            if(1==split){//主单
                orderBooking.setSplitSuccessCount(0);
                Long days = DateUtil.dateDiff(orderBooking.getMtCheckinDate(),"day",orderBooking.getMtCheckoutDate(),"yyyy-MM-dd");
                orderBooking.setSplitDays(days.intValue());
            }
        }else{
            orderBooking.setSplit(0);
        }
        orderBooking.setState(state).setCreateTime(new Date()).setModifyTime(new Date());
        if(!ObjectUtils.isEmpty(requstDesc)){
            orderBooking.setRemark(DateUtil.getCurrTime()+" "+requstDesc);
        }

        try{
            int save = mtHotelOrderBookingMapper.insert(orderBooking);
            if(save==1){
                //保存订单变化日志
                MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                stateHistory.setMtDistributorOrderId(orderBooking.getMtDistributorOrderId());
                stateHistory.setSwOrderId(swOrderId);
                stateHistory.setMtHotelId(orderBooking.getMtHotelId());
                stateHistory.setMasterOrderId(masterOrderId);
                stateHistory.setMtGoodsId(orderBooking.getMtGoodsId());
                stateHistory.setMethodName("保存预下单信息");
                stateHistory.setMethod("saveRequsetOrderBooking");
                stateHistory.setStatusCode(orderState);
                stateHistory.setStatusDesc("保存预下单信息");
                stateHistory.setMtOrderState(orderState);
                stateHistory.setClassJson(JSON.toJSONString(orderBooking));
                this.saveOrderStateHistory(stateHistory);

                //保存订单的产品信息
                List<MtHotelOrderCheckPricesVo> priceModels = mtHotelOrderCheckVo.getPriceModels();
                for (MtHotelOrderCheckPricesVo pri:priceModels){
                    MtHotelOrderBookingProducts mtHotelOrderBookingProducts = new MtHotelOrderBookingProducts();
                    mtHotelOrderBookingProducts.setId(StringUtil.getUUID());
                    mtHotelOrderBookingProducts.setMtDistributorOrderId(orderBooking.getMtDistributorOrderId());
                    mtHotelOrderBookingProducts.setMtOrderId(orderBooking.getMtOrderId());
                    mtHotelOrderBookingProducts.setMtSalePrice(pri.getSalePrice());
                    mtHotelOrderBookingProducts.setMtRoomNum(orderBooking.getMtRoomNum());
                    mtHotelOrderBookingProducts.setMtSubPrice(pri.getSubPrice());
                    mtHotelOrderBookingProducts.setMtSubRatio(pri.getSubRatio());
                    mtHotelOrderBookingProducts.setMtDate(pri.getDate());
                    mtHotelOrderBookingProducts.setMtDayType(pri.getDayType());
                    mtHotelOrderBookingProducts.setState(CommonEnums.STATE_NORMAL.getCode());
                    mtHotelOrderBookingProducts.setCreateTime(new Date());
                    mtHotelOrderBookingProducts.setModifyTime(mtHotelOrderBookingProducts.getCreateTime());
                    mtHotelOrderBookingProductsMapper.insert(mtHotelOrderBookingProducts);
                }

              /*  MtHotelOrderBookingDto mtHotelOrderBookingDto = new MtHotelOrderBookingDto();
                mtHotelOrderBookingDto.setMtHotelId(mtHotelOrderBookingParamVo.getHotelId())
                        .setMtDistributorOrderId(mtHotelOrderBookingParamVo.getDistributorOrderId())
                        .setMtGoodsId(mtHotelOrderBookingParamVo.getGoodsId())
                        .setMtPersonNames(mtHotelOrderBookingParamVo.getPersonNames())
                        .setMtContactName(mtHotelOrderBookingParamVo.getContactName())
                        .setMtContactPhone(mtHotelOrderBookingParamVo.getContactPhone())
                        .setMtArriveDate(mtHotelOrderBookingParamVo.getArriveDate())
                        .setMtCheckinDate(mtHotelOrderBookingParamVo.getCheckinDate())
                        .setMtCheckoutDate(mtHotelOrderBookingParamVo.getCheckoutDate())
                        .setMtCheckinDate(mtHotelOrderBookingParamVo.getCheckinDate())
                        .setMtRoomNum(mtHotelOrderBookingParamVo.getRoomNum())
                        .setMtTotalPrice(mtHotelOrderBookingParamVo.getTotalPrice())
                        .setMtSettlePrice(mtHotelOrderBookingParamVo.getSettlePrice())
                        .setMtComment(mtHotelOrderBookingParamVo.getComment())
                        .setMtPersonIdentities(mtHotelOrderBookingParamVo.getPersonIdentities())
                        .setMtNeedInvoice(mtHotelOrderBookingParamVo.getNeedInvoice());*/
                //保存到redis
                /*Map appendMap = new HashMap();
                appendMap.put(mtHotelOrderBookingDto.getMtDistributorOrderId(),mtHotelOrderBookingDto);
                redisSaveUpdateMtHotelOrderBookingInfos(CommonConstants.MEITUAN_HOTEL_ORDER_INFO,appendMap);*/
                return orderBooking;
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return null;
    }

    /**
     * redis 缓存酒店订单数据
     * Map appendMap    key = 酒店订单id，value=酒店订单dto对象
     */
    /*public void redisSaveUpdateMtHotelOrderBookingInfos(String rediskey,Map appendInfosMap){
        Map<String, MtHotelOrderBookingDto> redisMap = (Map<String, MtHotelOrderBookingDto>)redisService.get(rediskey);
        if(null != redisMap && redisMap.size()>0){
            redisMap.putAll(appendInfosMap);//加入putall覆盖旧数据s
        }else{
            redisMap=appendInfosMap;
        }
        redisService.set(rediskey,redisMap);
    }*/

    @Override
    public void updateStateOrderBookingByDistributorOrderId(String distributorOrderId,Integer orderStatus,String remark,Integer state,Integer poolSysState) {
        try{
            if(!StringUtils.isEmpty(distributorOrderId)){
                MtHotelOrderBooking record = new MtHotelOrderBooking();
                if(null != orderStatus){
                    record.setMtOrderState(orderStatus);
                }
                if(null != remark){
                    record.setRemark(remark);
                }
                if(null != state){
                    record.setState(state);//1 失效  0  有效
                }
                if(null != poolSysState){
                    record.setPoolSysState(poolSysState);
                }
                Example example = new Example(MtHotelOrderBooking.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("mtDistributorOrderId",distributorOrderId);
                mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
                /*Map map = new HashMap();
                map.put("mtOrderState",state);
                map.put("mtDistributorOrderId",distributorOrderId);
                mtHotelOrderBookingMapper.updateStateOrderBookingForUpdate(map);*/

            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * redis 缓存酒店订单数据
     * Map appendMap    key = 酒店订单id，value=酒店订单dto对象
     */
    /*public void redisSaveUpdateMtHotelOrderBookingInfos(String rediskey,Map appendInfosMap){
        Map<String, MtHotelOrderBookingDto> redisMap = (Map<String, MtHotelOrderBookingDto>)redisService.get(rediskey);
        if(null != redisMap && redisMap.size()>0){
            redisMap.putAll(appendInfosMap);//加入putall覆盖旧数据s
        }else{
            redisMap=appendInfosMap;
        }
        redisService.set(rediskey,redisMap);
    }*/

    @Override
    public void updateMasterOrderOper(String distributorOrderId,Integer orderStatus,Integer oper) {
        try{
            if(!StringUtils.isEmpty(distributorOrderId)){
                MtHotelOrderBooking record = new MtHotelOrderBooking();
                record.setMtOrderState(orderStatus);
                if(null != oper){
                    record.setOper(oper);
                }
                if(null != orderStatus){
                    record.setMtOrderState(orderStatus);
                }
                Example example = new Example(MtHotelOrderBooking.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("mtDistributorOrderId",distributorOrderId);
                mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * api预约下单（保存订单后，调用上游）
     *
     * 参数非法:测试账号无法预定该酒店产品，请更换酒店id<52786813,2491429>
     *{"code":0,"message":"成功","partnerId":3,"result":{"mtOrderId":null,"distributorOrderId":null,"code":2,"desc":"订单结算价校验失败, 结算价应该为19000"}}
     * @param mtHotelOrderBookingParamVo
     * @return
     */
    @Override
    public Result<Object> orderBookingApi(MtHotelOrderBookingParamVo mtHotelOrderBookingParamVo,Integer swTotalPrice) {
        String hotelId = mtHotelOrderBookingParamVo.getHotelId();
        String goodsId = mtHotelOrderBookingParamVo.getGoodsId();
        String personNames = mtHotelOrderBookingParamVo.getPersonNames();
        String contactName = mtHotelOrderBookingParamVo.getContactName();
        String contactPhone = mtHotelOrderBookingParamVo.getContactPhone();
        String arriveDate = mtHotelOrderBookingParamVo.getArriveDate();
        String checkinDate = mtHotelOrderBookingParamVo.getCheckinDate();
        String checkoutDate = mtHotelOrderBookingParamVo.getCheckoutDate();
        Integer roomNum = mtHotelOrderBookingParamVo.getRoomNum();
        Integer totalPrice = mtHotelOrderBookingParamVo.getTotalPrice();
        Integer settlePrice = mtHotelOrderBookingParamVo.getSettlePrice();
        String distributorOrderIdIsHhbOrderId_index = mtHotelOrderBookingParamVo.getDistributorOrderId();//美团序号订单号
        String swOrderId = distributorOrderIdIsHhbOrderId_index.substring(0,distributorOrderIdIsHhbOrderId_index.length()-3);
        /*MtHotelOrderBooking selectMtOrder1 = mtHotelOrderService.selectOneByMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
        if(null != selectMtOrder1){//过滤state状态 可能重复订单，，，，订单号只会有一条数据存在
            log.info("已下过单,重复订单,返回success");
            Result result =  new Result();
            result.setCode(CommonConstants.SUCCESS);
            result.setData(new MtHotelOrderBookingVo());
            result.setMsg("重复订单");
            //响应数据保存订单变化日志
            MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
            stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
            stateHistory.setSwOrderId(swOrderId);
            stateHistory.setMtHotelId(hotelId);
            stateHistory.setMtGoodsId(goodsId);
            stateHistory.setMtOrderId(null);//美团第三方平台订单id
            stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
            stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
            stateHistory.setStatusCode(null);
            stateHistory.setStatusDesc(null);
            stateHistory.setClassName("MtHotelOrderBookingVo");
            stateHistory.setClassJson("selectMtOrder1 库表已存在该下单订单号，订单重复");
            //保存日志
            saveOrderStateHistory(stateHistory);
            return result;
        }*/

        String comment = mtHotelOrderBookingParamVo.getComment();
        String personIdentities = mtHotelOrderBookingParamVo.getPersonIdentities();
        Integer needInvoice = mtHotelOrderBookingParamVo.getNeedInvoice();
        //MtHotelOrderBookingInvoiceParamVo invoice = mtHotelOrderBookingParamVo.getInvoice();
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("hotelId",hotelId);
        dataMap.put("goodsId",goodsId);
        dataMap.put("personNames",personNames);
        dataMap.put("contactName",contactName);
        dataMap.put("contactPhone",contactPhone);
        if(StringUtils.isEmpty(arriveDate)){
            MtHotelDetail mtHotelDetail = new MtHotelDetail();
            mtHotelDetail.setMtHotelId(hotelId);
            MtHotelDetail hotel = mtHotelDetailMapper.selectOne(mtHotelDetail);//最晚达到时间 查询酒店赋值
            if(null != hotel){
                if(null != hotel.getMtHotelCheckinTimeEnd() && !"0".equals(hotel.getMtHotelCheckinTimeEnd())){
                    dataMap.put("arriveDate",checkinDate+" "+hotel.getMtHotelCheckinTimeEnd()+":59");
                }else{
                    dataMap.put("arriveDate",checkinDate+" "+"23:59:59");
                }
            }else{
                return new Result<>("未找到酒店信息，请核实hotelId", CommonConstants.REQUEST_ERROR);
            }
            mtHotelOrderBookingParamVo.setArriveDate((String)dataMap.get("arriveDate"));
        }else{
            dataMap.put("arriveDate",arriveDate);
        }

        dataMap.put("checkinDate",checkinDate);
        dataMap.put("checkoutDate",checkoutDate);
        dataMap.put("roomNum",roomNum);
        dataMap.put("totalPrice",totalPrice);
        dataMap.put("settlePrice",settlePrice);
        dataMap.put("distributorOrderId",distributorOrderIdIsHhbOrderId_index);
        dataMap.put("comment",comment);
        dataMap.put("personIdentities",personIdentities);
        dataMap.put("needInvoice",needInvoice);
        data = JSON.toJSONString(dataMap);

        log.info("预下单请求参数swOrderId={},data={}",swOrderId,data);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod(),meituanSaveApiLogTask);//"{\"code\":0,\"message\":\"成功\",\"partnerId\":3,\"result\":{\"mtOrderId\":2558044731377262115,\"distributorOrderId\":\"hhb20200612002\",\"code\":0,\"desc\":\"下单成功\"}}";//
        if(null == response){
            SendUtils.dingMsgNotLog("[FAILED-BOOKING] 校验通过但美团预下单失败，将延时处理 ",DateUtil.getCurrTime()+"：null1:"+response+" 订单号："+swOrderId,MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);

            MtHotelOrderBookingVo mtHotelOrderBookingVo = new MtHotelOrderBookingVo();
            mtHotelOrderBookingVo.setDesc("酒店预约下单接口数据异常 response null："+response);
            this.saveRequsetOrderBooking(mtHotelOrderBookingVo,mtHotelOrderBookingParamVo,MtHotelEnums.orderStateEnum.FAILED.getCode(),CommonEnums.STATE_ERROR.getCode(),distributorOrderIdIsHhbOrderId_index,swOrderId,null,null,swTotalPrice);

            return new Result<>(CommonConstants.REQUEST_ERROR,"接口异常，返回null");
        }
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        MtHotelOrderBookingVo mtHotelOrderBookingVo = new MtHotelOrderBookingVo();

        if("0".equals(String.valueOf(responseJson.get("code")))){
            String result = responseJson.getString("result");
            if(null != result){

                try {
                    mtHotelOrderBookingVo = JSON.parseObject(result, MtHotelOrderBookingVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(null == mtHotelOrderBookingVo){
                    log.error("////////////////MTAPIERROR///////////////////酒店预约下单接口数据异常 result parse vo error：{}",result);
                    //创建订单,当前下单失败 并保存日志


                    //响应数据保存订单变化日志
                    MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                    stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
                    stateHistory.setSwOrderId(swOrderId);
                    stateHistory.setMtHotelId(hotelId);
                    stateHistory.setMtGoodsId(goodsId);
                    stateHistory.setMtOrderId(mtHotelOrderBookingVo.getMtOrderId());
                    stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
                    stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
                    stateHistory.setStatusCode(mtHotelOrderBookingVo.getCode());
                    stateHistory.setStatusDesc(mtHotelOrderBookingVo.getDesc());
                    stateHistory.setClassName("MtHotelOrderBookingVo");
                    stateHistory.setClassJson("返回bookingvo为空 null2："+response);
                    stateHistory.setRemark(response);
                    //保存日志
                    saveOrderStateHistory(stateHistory);

                    mtHotelOrderBookingVo = new MtHotelOrderBookingVo();
                    mtHotelOrderBookingVo.setDesc("酒店预约下单接口数据异常 result parse vo error："+result);
                    this.saveRequsetOrderBooking(mtHotelOrderBookingVo,mtHotelOrderBookingParamVo,MtHotelEnums.orderStateEnum.FAILED.getCode(),CommonEnums.STATE_ERROR.getCode(),distributorOrderIdIsHhbOrderId_index,swOrderId,null,null,swTotalPrice);

                    SendUtils.dingMsgNotLog("[FAILED-BOOKING] 校验通过但美团预下单失败，将延时处理 ",DateUtil.getCurrTime()+"：null2:"+response+" 订单号："+swOrderId,MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);

                    return new Result<>("parse error", CommonConstants.PARSE_ERROR);
                }else{
                    //响应数据保存订单变化日志
                    MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                    stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
                    stateHistory.setSwOrderId(swOrderId);
                    stateHistory.setMtHotelId(hotelId);
                    stateHistory.setMtGoodsId(goodsId);
                    stateHistory.setMtOrderId(mtHotelOrderBookingVo.getMtOrderId());
                    stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
                    stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
                    stateHistory.setStatusCode(mtHotelOrderBookingVo.getCode());
                    stateHistory.setStatusDesc(mtHotelOrderBookingVo.getDesc());
                    stateHistory.setClassName("MtHotelOrderBookingVo");
                    stateHistory.setClassJson(JSON.toJSONString(mtHotelOrderBookingVo));
                    stateHistory.setRemark(response);
                    //再一层code判断
                    /***
                     * 下单结果码：
                     * 0 下单成功
                     * 1 系统繁忙，请稍后重试
                     * 2 产品已变价
                     * 3 重复订单, 对应下单失败
                     * 4 产品已售完，扣减库存失败
                     * 5 账户扣款失败
                     * 10 产品被拉黑, 不允许购买
                     * 11 该产品如选择预计到店时间在 XXXX 之后的，需支付相应担保金，第一期暂不支持下担保产品的订单!
                     * 20 其它
                     */
                    if(0==mtHotelOrderBookingVo.getCode()
                            || (!ObjectUtils.isEmpty(mtHotelOrderBookingVo.getDesc()) && mtHotelOrderBookingVo.getDesc().contains("非支付失败"))){
                        //预下单成功后，JOB_ING更新为失效时间6秒
                        redisTemplate.opsForValue().set(MeituanConstants.REDIS_KEY_HEAD_MT_ORDER_JOB_ING_VALUE_ORDER_ID+swOrderId,swOrderId,30,TimeUnit.SECONDS);

                        SendUtils.dingMsgNotLog("[WAITING-NOTICE] 预下单已提交 ",DateUtil.getCurrTime()+"："+distributorOrderIdIsHhbOrderId_index,MessageEnums.genre.ORDER_NOTICY.getCode(),restTemplate);
                        //创建订单,保存订单 成功
                        MtHotelOrderBooking mtHotelOrderBooking = this.saveRequsetOrderBooking(mtHotelOrderBookingVo,mtHotelOrderBookingParamVo,MtHotelEnums.orderStateEnum.BOOKING.getCode(),CommonEnums.STATE_NORMAL.getCode(),distributorOrderIdIsHhbOrderId_index,swOrderId,null,null,swTotalPrice);

                        //下单成功
                        stateHistory.setMtOrderState(MtHotelEnums.orderStateEnum.BOOKING.getCode());
                        //保存日志
                        saveOrderStateHistory(stateHistory);

                        if(null == mtHotelOrderBooking){
                            //美团订单保存异常
                            log.error(">>>>>>>>>>>>>>>>>>>>>>>> 预下单接口，接口请求成功，美团订单数据库保存异常，需及时检查！保存参数{},上游响应{}"+ JSON.toJSONString(mtHotelOrderBookingParamVo),responseJson);
                        }else{
                            //缓存预定中待确认(待异步通知)的订单（定时器每一分钟催单超过6分钟未确认订单）
                            //MtHotelOrderBookingDto mtHotelOrderBookingDto = new MtHotelOrderBookingDto();
                            //StreamUtils.BeanUtil.copyPropertiesIgnoreCase(mtHotelOrderBooking,mtHotelOrderBookingDto);
                            //joinHotelOrderWaitConfirmRedis(mtHotelOrderBookingDto);
                        }
                        return new Result<>(mtHotelOrderBookingVo);
                    }else{
                        //保存日志
                        saveOrderStateHistory(stateHistory);
                        //外部处理延时
                        SendUtils.dingMsgNotLog("[FAILED-BOOKING]下单前校验成功，但美团预下单失败，将延时处理 ",DateUtil.getCurrTime()+"："+response+" 订单号："+swOrderId,MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);

                        if(null == redisService.get("swmt_booking_no_money_send_close")){
                            if(!ObjectUtils.isEmpty(mtHotelOrderBookingVo.getDesc()) && mtHotelOrderBookingVo.getDesc().contains("账户余额为零")){
                                log.info("[FAILED-BOOKING] >>>>>>>> 账户余额为零：mtHotelOrderBookingVo={}",GsonUtils.GsonString(mtHotelOrderBookingVo));
                                if(null == redisService.get("swmt_booking_no_money_send")){
                                    log.info("[FAILED-BOOKING] >>>>>>>> 账户余额为零={}",GsonUtils.GsonString(mtHotelOrderBookingVo));
                                    //SendUtils.sendWarnPhone("一线预下单失败，"+mtHotelOrderBookingVo.getDesc(), 2,restTemplate);
                                    SendUtils.sendWarnPhone("二线预下单失败账户异常请关注", 2,restTemplate);
                                    SendUtils.dingMsgNotLog("二线预下单失败账户异常请关注 ",DateUtil.getCurrTime()+"："+response+" 订单号："+swOrderId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                    redisService.setUnit("swmt_booking_no_money_send",1,1L,TimeUnit.HOURS);
                                }
                            }
                        }

                        //创建订单,当前下单失败 并保存日志
                        mtHotelOrderBookingVo.setDesc("酒店预约下单接口数据异常 result code!=0："+result);
                        this.saveRequsetOrderBooking(mtHotelOrderBookingVo,mtHotelOrderBookingParamVo,MtHotelEnums.orderStateEnum.FAILED.getCode(),CommonEnums.STATE_ERROR.getCode(),distributorOrderIdIsHhbOrderId_index,swOrderId,null,null,swTotalPrice);

                        return new Result<>(mtHotelOrderBookingVo);
                    }
                }
            }else{
                //创建订单,当前下单失败 并保存日志   外部处理延时
                SendUtils.dingMsgNotLog("[FAILED-BOOKING] 校验通过但美团预下单失败，将延时处理 ",DateUtil.getCurrTime()+"：接口请求成功result null 异常："+response+" 订单号："+swOrderId,MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);

                log.error(">>>>>>>>>>>>>>>>>>>>>>>> 预下单接口，接口请求成功但result异常，需及时检查！保存参数{},上游响应内容{}"+ JSON.toJSONString(mtHotelOrderBookingParamVo),responseJson);

                //响应数据保存订单变化日志
                MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
                stateHistory.setSwOrderId(swOrderId);
                stateHistory.setMtHotelId(hotelId);
                stateHistory.setMtGoodsId(goodsId);
                stateHistory.setMtOrderId(null);
                stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
                stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
                stateHistory.setStatusCode(null);
                stateHistory.setStatusDesc(null);
                stateHistory.setClassName("MtHotelOrderBookingVo");
                stateHistory.setClassJson(DateUtil.getCurrTime()+"：接口请求成功result null 异常："+response);
                stateHistory.setRemark(response);
                //保存日志
                saveOrderStateHistory(stateHistory);

                mtHotelOrderBookingVo = new MtHotelOrderBookingVo();
                mtHotelOrderBookingVo.setDesc("酒店预约下单接口返回null："+result);
                this.saveRequsetOrderBooking(mtHotelOrderBookingVo,mtHotelOrderBookingParamVo,MtHotelEnums.orderStateEnum.BOOKING.getCode(),CommonEnums.STATE_ERROR.getCode(),distributorOrderIdIsHhbOrderId_index,swOrderId,null,null,swTotalPrice);


                return new Result<>(response, CommonConstants.REQUEST_ERROR);
            }
        }else{
            //创建订单,当前下单失败 并保存日志   外部处理延时
            SendUtils.dingMsgNotLog("校验通过但美团预下单失败，将延时处理 ",DateUtil.getCurrTime()+"："+response,MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);

            log.error(">>>>>>>>>>>>>>>>>>>>>>>> 预下单接口，接口请求上游返回失败！保存参数={},上游响应={}", JSON.toJSONString(mtHotelOrderBookingParamVo),responseJson);
            //响应数据保存订单变化日志
            MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
            stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
            stateHistory.setSwOrderId(swOrderId);
            stateHistory.setMtHotelId(hotelId);
            stateHistory.setMtGoodsId(goodsId);
            stateHistory.setMtOrderId(null);
            stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
            stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
            stateHistory.setStatusCode(null);
            stateHistory.setStatusDesc(null);
            stateHistory.setClassName("MtHotelOrderBookingVo");
            stateHistory.setClassJson(DateUtil.getCurrTime()+"：接口请求上游返回失败："+response);
            stateHistory.setRemark(response);
            //保存日志
            saveOrderStateHistory(stateHistory);

            mtHotelOrderBookingVo.setDesc("酒店预约下单接口返回失败："+responseJson.toString());
            this.saveRequsetOrderBooking(mtHotelOrderBookingVo,mtHotelOrderBookingParamVo,MtHotelEnums.orderStateEnum.BOOKING.getCode(),CommonEnums.STATE_ERROR.getCode(),distributorOrderIdIsHhbOrderId_index,swOrderId,null,null,swTotalPrice);

            return new Result<>(response, CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     * 拆单子单，向美团api发起预下单
     * @param mtHotelOrderBookingParamVo
     * @param masterOrderId
     * @return
     */
    @Override
    public Result<Object> orderBookingSplitOrder(MtHotelOrderBookingParamVo mtHotelOrderBookingParamVo, String masterOrderId) {
        String hotelId = mtHotelOrderBookingParamVo.getHotelId();
        String goodsId = mtHotelOrderBookingParamVo.getGoodsId();
        String personNames = mtHotelOrderBookingParamVo.getPersonNames();
        String contactName = mtHotelOrderBookingParamVo.getContactName();
        String contactPhone = mtHotelOrderBookingParamVo.getContactPhone();
        String arriveDate = mtHotelOrderBookingParamVo.getArriveDate();
        String checkinDate = mtHotelOrderBookingParamVo.getCheckinDate();
        String checkoutDate = mtHotelOrderBookingParamVo.getCheckoutDate();
        Integer roomNum = mtHotelOrderBookingParamVo.getRoomNum();
        Integer totalPrice = mtHotelOrderBookingParamVo.getTotalPrice();
        Integer settlePrice = mtHotelOrderBookingParamVo.getSettlePrice();
        String distributorOrderIdIsHhbOrderId_index = mtHotelOrderBookingParamVo.getDistributorOrderId();//美团序号订单号

        String comment = mtHotelOrderBookingParamVo.getComment();
        String personIdentities = mtHotelOrderBookingParamVo.getPersonIdentities();
        Integer needInvoice = mtHotelOrderBookingParamVo.getNeedInvoice();
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("hotelId",hotelId);
        dataMap.put("goodsId",goodsId);
        dataMap.put("personNames",personNames);
        dataMap.put("contactName",contactName);
        dataMap.put("contactPhone",contactPhone);
        if(StringUtils.isEmpty(arriveDate)){
            MtHotelDetail mtHotelDetail = new MtHotelDetail();
            mtHotelDetail.setMtHotelId(hotelId);
            MtHotelDetail hotel = mtHotelDetailMapper.selectOne(mtHotelDetail);//最晚达到时间 查询酒店赋值
            if(null != hotel){
                if(null != hotel.getMtHotelCheckinTimeEnd() && !"0".equals(hotel.getMtHotelCheckinTimeEnd())){
                    dataMap.put("arriveDate",checkinDate+" "+hotel.getMtHotelCheckinTimeEnd()+":59");
                }else{
                    dataMap.put("arriveDate",checkinDate+" "+"23:59:59");
                }
            }else{
                return new Result<>("未找到酒店信息，请核实hotelId", CommonConstants.REQUEST_ERROR);
            }
            mtHotelOrderBookingParamVo.setArriveDate((String)dataMap.get("arriveDate"));
        }else{
            dataMap.put("arriveDate",arriveDate);
        }

        dataMap.put("checkinDate",checkinDate);
        dataMap.put("checkoutDate",checkoutDate);
        dataMap.put("roomNum",roomNum);
        dataMap.put("totalPrice",totalPrice);
        dataMap.put("settlePrice",settlePrice);
        dataMap.put("distributorOrderId",distributorOrderIdIsHhbOrderId_index);
        dataMap.put("comment",comment);
        dataMap.put("personIdentities",personIdentities);
        dataMap.put("needInvoice",needInvoice);
        data = JSON.toJSONString(dataMap);

        String  response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod(),meituanSaveApiLogTask);
        SendUtils.dingMsgNotLog("[BOOKING]预下单，子单提交 ",DateUtil.getCurrTime()+" 请求参数："+data+", 美团接口返回："+response,MessageEnums.genre.ORDER_NOTICY.getCode(),restTemplate);
        /*//发起请求
        if(distributorOrderIdIsHhbOrderId_index.substring(distributorOrderIdIsHhbOrderId_index.length()-3,distributorOrderIdIsHhbOrderId_index.length()).contains("01")){
            response = "{\"code\":0,\"message\":\"成功\",\"partnerId\":3,\"result\":{\"mtOrderId\":2558044731304129059,\"distributorOrderId\":\""+distributorOrderIdIsHhbOrderId_index+"\",\"code\":0,\"desc\":\"下单成功\"}}";//MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod(),meituanSaveApiLogTask);
        }else{
            response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod(),meituanSaveApiLogTask);
        }*/



        if(null == response){
            //外部处理延时
            return new Result<>("接口异常，返回null",CommonConstants.REQUEST_ERROR);
        }
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        MtHotelOrderBookingVo mtHotelOrderBookingVo = new MtHotelOrderBookingVo();

        if("0".equals(String.valueOf(responseJson.get("code")))){
            String result = responseJson.getString("result");
            if(null != result){
                try {
                    mtHotelOrderBookingVo = JSON.parseObject(result, MtHotelOrderBookingVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(null == mtHotelOrderBookingVo){
                    log.error("////////////////MTAPIERROR///////////////////酒店预约下单接口数据异常 result parse vo error：{}",result);
                    //创建订单,当前下单失败 并保存日志
                    //响应数据保存订单变化日志
                    MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                    stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
                    stateHistory.setSwOrderId(null);
                    stateHistory.setMasterOrderId(masterOrderId);
                    stateHistory.setMtHotelId(hotelId);
                    stateHistory.setMtGoodsId(goodsId);
                    stateHistory.setMtOrderId(mtHotelOrderBookingVo.getMtOrderId());
                    stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
                    stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
                    stateHistory.setStatusCode(mtHotelOrderBookingVo.getCode());
                    stateHistory.setStatusDesc(mtHotelOrderBookingVo.getDesc());
                    stateHistory.setClassName("MtHotelOrderBookingVo");
                    stateHistory.setClassJson("返回bookingvo为空 null2："+response);
                    stateHistory.setRemark(response);
                    saveOrderStateHistory(stateHistory);
                    return new Result<>("返回bookingvo为空 null2："+response, CommonConstants.PARSE_ERROR);
                }else{
                    //响应数据保存订单变化日志
                    MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                    stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
                    stateHistory.setSwOrderId(null);
                    stateHistory.setMasterOrderId(masterOrderId);
                    stateHistory.setMtHotelId(hotelId);
                    stateHistory.setMtGoodsId(goodsId);
                    stateHistory.setMtOrderId(mtHotelOrderBookingVo.getMtOrderId());
                    stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
                    stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
                    stateHistory.setStatusCode(mtHotelOrderBookingVo.getCode());
                    stateHistory.setStatusDesc(mtHotelOrderBookingVo.getDesc());
                    stateHistory.setClassName("MtHotelOrderBookingVo");
                    stateHistory.setClassJson(JSON.toJSONString(mtHotelOrderBookingVo));
                    stateHistory.setRemark(response);
                    stateHistory.setMtOrderState(MtHotelEnums.orderStateEnum.BOOKING.getCode());
                    saveOrderStateHistory(stateHistory);
                    //再一层code判断
                    /***
                     * 下单结果码：
                     * 0 下单成功
                     * 1 系统繁忙，请稍后重试
                     * 2 产品已变价
                     * 3 重复订单, 对应下单失败
                     * 4 产品已售完，扣减库存失败
                     * 5 账户扣款失败
                     * 10 产品被拉黑, 不允许购买
                     * 11 该产品如选择预计到店时间在 XXXX 之后的，需支付相应担保金，第一期暂不支持下担保产品的订单!
                     * 20 其它
                     */
                    if(0==mtHotelOrderBookingVo.getCode()){
                        //SendUtils.dingMsgNotLog("[WAITING-SPLIT] 子单预下单已提交 ",DateUtil.getCurrTime()+" 子订单号："+distributorOrderIdIsHhbOrderId_index+" 主订单号："+masterOrderId,MessageEnums.genre.ORDER_NOTICY.getCode(),masterOrderId,restTemplate);
                        return new Result<>(mtHotelOrderBookingVo);
                    }else{
                        log.info("拆单下单,酒店预约下单接口数据异常 result code!=0："+result);
                        return new Result<>("拆单下单,酒店预约下单接口数据异常 result code!=0："+mtHotelOrderBookingVo,CommonConstants.REQUEST_ERROR);
                    }
                }
            }else{
                log.error(">>>>>>>>>>>>>>>>>>>>>>>>"+DateUtil.getCurrTime()+"：接口请求成功result null 异常："+response);
                //响应数据保存订单变化日志
                MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
                stateHistory.setSwOrderId(null);
                stateHistory.setMasterOrderId(masterOrderId);
                stateHistory.setMtHotelId(hotelId);
                stateHistory.setMtGoodsId(goodsId);
                stateHistory.setMtOrderId(null);
                stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
                stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
                stateHistory.setStatusCode(null);
                stateHistory.setStatusDesc(null);
                stateHistory.setClassName("MtHotelOrderBookingVo");
                stateHistory.setClassJson(DateUtil.getCurrTime()+"：接口请求成功result null 异常："+response);
                stateHistory.setRemark(response);
                saveOrderStateHistory(stateHistory);
                return new Result<>(DateUtil.getCurrTime()+"：接口请求成功result null 异常："+response, CommonConstants.REQUEST_ERROR);
            }
        }else{
            //创建订单,当前下单失败 并保存日志   外部处理延时
            log.error(">>>>>>>>>>>>>>>>>>>>>>>> 预下单接口，接口请求上游返回失败！保存参数={},上游响应={}", JSON.toJSONString(mtHotelOrderBookingParamVo),responseJson);
            //响应数据保存订单变化日志
            MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
            stateHistory.setMtDistributorOrderId(distributorOrderIdIsHhbOrderId_index);
            stateHistory.setSwOrderId(null);
            stateHistory.setMasterOrderId(masterOrderId);
            stateHistory.setMtHotelId(hotelId);
            stateHistory.setMtGoodsId(goodsId);
            stateHistory.setMtOrderId(null);
            stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getMethod());
            stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_BOOKING.getName());
            stateHistory.setStatusCode(null);
            stateHistory.setStatusDesc(null);
            stateHistory.setClassName("MtHotelOrderBookingVo");
            stateHistory.setClassJson(DateUtil.getCurrTime()+"：接口请求上游返回失败："+response);
            stateHistory.setRemark(response);
            //保存日志
            saveOrderStateHistory(stateHistory);
            return new Result<>("酒店预约下单接口返回失败："+response, CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     * 加入缓存  未确认订单
     * mtOrderId 上游返回的下单id
     * @param mtHotelOrderBookingDto
     */
    public void joinHotelOrderWaitConfirmRedis(MtHotelOrderBookingDto mtHotelOrderBookingDto){
        Map<String,MtHotelOrderBookingDto> putRedisMap = new HashMap<>();
        putRedisMap.put(mtHotelOrderBookingDto.getMtOrderId(),mtHotelOrderBookingDto);
        Map<String,MtHotelOrderBookingDto> redisMap = (Map<String,MtHotelOrderBookingDto>)redisTemplate.opsForValue().get(MeituanConstants.REDIS_MT_HOTEL_ORDER_WAIT_CONFIRM_WAIT_REMIND);
        if(null != redisMap && redisMap.size()>0){
            redisMap.putAll(putRedisMap);
        }else{
            redisMap = putRedisMap;
        }
        redisTemplate.opsForValue().set(MeituanConstants.REDIS_MT_HOTEL_ORDER_WAIT_CONFIRM_WAIT_REMIND,redisMap);

    }
    /**
     * 加入缓存  未确认订单
     * mtOrderId 上游返回的下单id
     * @param mtOrderId
     */
    public void removeHotelOrderWaitConfirmRedis(String mtOrderId){
        Map<String,MtHotelOrderBookingDto> redisMap = (Map<String,MtHotelOrderBookingDto>)redisTemplate.opsForValue().get(MeituanConstants.REDIS_MT_HOTEL_ORDER_WAIT_CONFIRM_WAIT_REMIND);
        if(null != redisMap && redisMap.size()>0){
            redisMap.remove(mtOrderId);
            redisTemplate.opsForValue().set(MeituanConstants.REDIS_MT_HOTEL_ORDER_WAIT_CONFIRM_WAIT_REMIND,redisMap);
        }
    }



    /**
     * 保存上游订单状态相关信息日志
     */
    @Override
    public void saveOrderStateHistory(MtHotelOrderStateHistory stateHistory){
        try{
            stateHistory.setId(UUID.randomUUID().toString());
            stateHistory.setState(CommonEnums.STATE_NORMAL.getCode());
            stateHistory.setModifyTime(new Date());
            stateHistory.setCreateTime(new Date());
            mtHotelOrderStateHistoryMapper.insert(stateHistory);
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * 获取处理中订单(确认中,取消中)
     * @return
     */
    @Override
    public Result<Object> getHotelOrderDealing(String gtTime) {
        Map<String,String> map = new HashMap();
        map.put("gtTime",gtTime);
        List<MtHotelOrderBookingDealingDto> list = mtHotelOrderBookingMapper.getPageHotelOrderDealing(map);
        if(null == list || list.size()==0){
            return new Result<>();
        }
        return new Result<>(JSON.toJSONString(list),"success");
    }

    /**
     * 判断该携程id是否已提交过订单 state=0  则不可再提交，存在说明有订单在处理
     * @return
     */
    public List<MtHotelOrderBooking> selectOneBySwOrderIsVail(String swOrderId) {
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("swOrderId",swOrderId);
        criteria.andEqualTo("state",0);
        List<MtHotelOrderBooking> mtHotelOrderBooking = mtHotelOrderBookingMapper.selectByExample(example);
        if(null == mtHotelOrderBooking || mtHotelOrderBooking.size()==0){
            return null;
        }
        log.info("selectOneBySwOrderIsVail mtHotelOrderBooking ="+ JSON.toJSONString(mtHotelOrderBooking));
        return mtHotelOrderBooking;
    }
    /**
     * 订单取消
     * {"code":0,"message":"成功","partnerId":3,"result":{"mtOrderId":2558044731055351971,"distributorOrderId":"hhb20200610001","code":5,"desc":"订单取消中"}}
     * @param mtHotelOrderCancelParamVo
     * @return
     */
    @Override
    public Result<Object> orderCancelApi(MtHotelOrderCancelParamVo mtHotelOrderCancelParamVo) {

        String distributorOrderId_index = mtHotelOrderCancelParamVo.getDistributorOrderId();

        MtHotelOrderBooking selectValiSwOrderidMtOrder = this.selectOneByMtDistributorOrderId(distributorOrderId_index);

        if(null == redisService.get("booking_to_split_close")){//如果该pool单时被拆单的，则该pool单的disId子单和mtOrderId子单 需要赋值为美团主单那边的信息
            Result checkIsMasterCancel = mtHotelOrderDealSplitService.checkIsMasterOrderApplyCancel(selectValiSwOrderidMtOrder);
            if(checkIsMasterCancel.getCode()==CommonConstants.SUCCESS){
                return checkIsMasterCancel;
            }
        }

        String swOrderId = null;
        String masterOrderId = null;
        if(null != selectValiSwOrderidMtOrder){
            swOrderId = selectValiSwOrderidMtOrder.getSwOrderId();
            masterOrderId = selectValiSwOrderidMtOrder.getMasterOrderId();
        }

        long mtOrderId = mtHotelOrderCancelParamVo.getMtOrderId();
        String cancelReason = mtHotelOrderCancelParamVo.getCancelReason();
        if(null == cancelReason){
            cancelReason = "取消";
        }
        Integer cancelCheck = mtHotelOrderCancelParamVo.getCancelCheck();
        if(null == cancelCheck){
            cancelCheck = 0;//正常取消 0
        }
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("distributorOrderId",distributorOrderId_index);
        dataMap.put("mtOrderId",mtOrderId);
        dataMap.put("cancelReason",cancelReason);
        dataMap.put("cancelCheck",cancelCheck);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_CANCEL.getMethod(),meituanSaveApiLogTask);
        //"{\"code\":0,\"message\":\"成功\",\"partnerId\":12734,\"result\":{\"mtOrderId\":null,\"distributorOrderId\":null,\"code\":5,\"desc\":null}}";
        //处理响应数据  美团请求接口，响应参数 {"code":0,"message":"成功","partnerId":12734,"result":{"mtOrderId":null,"distributorOrderId":null,"code":0,"desc":null}}  已取消成功过返回该示例
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))){
            String result = responseJson.getString("result");
            if(null != result){
                MtHotelOrderCancelVo mtHotelOrderCancelApiResponseVo = null;
                try {
                    mtHotelOrderCancelApiResponseVo = JSON.parseObject(result, MtHotelOrderCancelVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(null == mtHotelOrderCancelApiResponseVo){
                    log.error("////////////////MTAPIERROR///////////////////酒店订单取消接口数据异常 result parse vo error：{}",result);
                    return new Result<>("parse error", CommonConstants.PARSE_ERROR);
                }else{
                    //保存订单状态日志
                    MtHotelOrderStateHistory stateCancelHistory = new MtHotelOrderStateHistory();
                    stateCancelHistory.setMtDistributorOrderId(distributorOrderId_index);
                    stateCancelHistory.setSwOrderId(swOrderId);
                    stateCancelHistory.setMasterOrderId(masterOrderId);
                    stateCancelHistory.setMtHotelId(null);
                    stateCancelHistory.setMtGoodsId(null);
                    stateCancelHistory.setMtOrderId(String.valueOf(mtOrderId));
                    stateCancelHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_CANCEL.getMethod());
                    stateCancelHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_CANCEL.getName());
                    stateCancelHistory.setStatusCode(mtHotelOrderCancelApiResponseVo.getCode());
                    if(null == mtHotelOrderCancelApiResponseVo.getDistributorOrderId() && null == mtHotelOrderCancelApiResponseVo.getDesc()){
                        stateCancelHistory.setStatusDesc("该订单已取消成功过，被再次调用");
                    }else{
                        stateCancelHistory.setStatusDesc(mtHotelOrderCancelApiResponseVo.getDesc());
                    }
                    stateCancelHistory.setRemark(JSON.toJSONString(dataMap));
                    stateCancelHistory.setClassName("MtHotelOrderCancelVo");
                    stateCancelHistory.setClassJson(JSONObject.toJSONString(response));


                    //再一层code判断
                    /**
                     * 0 取消成功
                     * 1 系统繁忙
                     * 2 取消失败（超过最晚可取消时间；用户已入住等原因）
                     * 3 订单号不存在
                     * 4 取消失败，产品不允许取消
                     * 5 订单取消中
                     * 10 订单已经确认
                     * 20 其它
                     */
                    if(0==mtHotelOrderCancelApiResponseVo.getCode()){
                        //取消成功
                        this.updateStateOrderBookingByDistributorOrderId(mtHotelOrderCancelApiResponseVo.getDistributorOrderId(),MtHotelEnums.orderStateEnum.CANCELSUCCSS.getCode(),null,null,null);

                        stateCancelHistory.setMtOrderState(MtHotelEnums.orderStateEnum.CANCELSUCCSS.getCode());
                    }else  if(5==mtHotelOrderCancelApiResponseVo.getCode()){
                        //取消中
                        this.updateStateOrderBookingByDistributorOrderId(mtHotelOrderCancelApiResponseVo.getDistributorOrderId(),MtHotelEnums.orderStateEnum.CANCELING.getCode(),null,null,null);
                        stateCancelHistory.setMtOrderState(MtHotelEnums.orderStateEnum.CANCELING.getCode());
                    }else{
                        //请求成功但为取消失败（多种失败原因code）,取消失败，当前订单状态不做变更
                        stateCancelHistory.setMtOrderState(MtHotelEnums.orderStateEnum.CANCELFAILED.getCode());
                    }
                    //保存日志
                    saveOrderStateHistory(stateCancelHistory);
                    return new Result<>(mtHotelOrderCancelApiResponseVo);
                }
            }else{
                return new Result<>("error", CommonConstants.REQUEST_ERROR);
            }
        }else{
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }

    private MtHotelOrderBooking selectValiOneBySwOderId(String distributorOrderIdSwOrderId) {
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("swOrderId",distributorOrderIdSwOrderId);
        criteria.andEqualTo("state",0);//有效的
        MtHotelOrderBooking mtHotelOrderBooking = mtHotelOrderBookingMapper.selectOneByExample(example);
        return mtHotelOrderBooking;
    }

    /**
     * 定时器调用该方法，判断处理中（确认中和取消中）订单是否已改变状态，进行订单更新
     * @param dtoIds
     * @return
     */
    @Override
    public Result<Object> quartzQueryDealingOrderAndUpdateOrder(List<MtHotelOrderBookingDealingDto> dtoIds) {
        //美团查询订单接口（600次/分钟  10万次/天），暂不考虑次数限制
        for (MtHotelOrderBookingDealingDto dto:dtoIds){
            MtHotelOrderQueryParamVo mtHotelOrderQueryParamVo = new MtHotelOrderQueryParamVo();
            mtHotelOrderQueryParamVo.setMtOrderId(Long.valueOf(dto.getMtOrderId()));
            mtHotelOrderQueryParamVo.setDistributorOrderId(dto.getMtDistributorOrderId());//序号订单号 不是携程订单号
            orderQuery(mtHotelOrderQueryParamVo);
            //判断订单状态

            //更新订单前要先行锁查询出该条订单，因为上游主动推送notify那边也会有操作该条订单的可能
            //selectoneforupdate
            //判断数据库中该订单如果已经不是处理中状态（可能nontify那边处理了）（处理中状态指的是等待确认中和取消中），则不做下面的操作，
            //反之继续操作

            //update

            //有状态变更的订单存到redis，定时器那边方法结束前，取出reids中的订单，调用携程接口，推送给携程状态变化的订单

            //待确认订单保存再缓存中，当美团notify+定时器主动查询订单变更时移除缓存
        }

        return null;
    }

    @Override
    public MtHotelOrderBooking selectOneByMtDistributorOrderId(String distributorOrderIdIndex) {
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mtDistributorOrderId",distributorOrderIdIndex);
        criteria.andEqualTo("state",0);
        MtHotelOrderBooking mtHotelOrderBooking = mtHotelOrderBookingMapper.selectOneByExample(example);
        return mtHotelOrderBooking;
    }

    public List<MtHotelOrderBooking> selectOneByMtDistributorOrderIdNotVail(String distributorOrderId) {
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mtDistributorOrderId",distributorOrderId);
        criteria.andEqualTo("state",1);
        List<MtHotelOrderBooking> mtHotelOrderBooking = mtHotelOrderBookingMapper.selectByExample(example);
        return mtHotelOrderBooking;
    }

    /**
     * 查询出该对象，forupdate 排他锁，当一个事务的操作未完成时候，其他事务可以读取但是不能写入或更新。
     * 数据被forupdate前要确保数据有存在，要先正常selectone出来；
     * 且forupdate查询出来后，一定要有后面操作update对象，才能释放锁。
     * @return
     */
    @Override
    public MtHotelOrderBooking selectOneByDisOrderIdForUpdate(String disOrderId_index) {
        Map map = new HashMap();
        map.put("mtDistributorOrderId",disOrderId_index);
        MtHotelOrderBooking mtHotelOrderBooking = mtHotelOrderBookingMapper.selectOneDisOrderIdForUpdate(map);
        return mtHotelOrderBooking;
    }

    /**
     * 订单查询
     * @param mtHotelOrderQueryParamVo
     * @return
     */
    @Override
    public Result<Object> orderQuery(MtHotelOrderQueryParamVo mtHotelOrderQueryParamVo) {
        List<MtHotelOrderQueryParamVo> list = new ArrayList<>();
        list.add(mtHotelOrderQueryParamVo);
        Result result = this.orderQueryBatch(list);
        if(result.getCode()==CommonConstants.SUCCESS){
            if(null != result.getData()){
                List<MtHotelOrderQueryDetailVo> detail = new ArrayList<>();
                detail = JSON.parseArray(result.getData().toString(), MtHotelOrderQueryDetailVo.class);
                return  new Result<>(detail);
            }else{
                return  new Result<>("null",CommonConstants.REQUEST_ERROR);
            }
        }else{
            return  new Result<>("error null",CommonConstants.REQUEST_ERROR);
        }
    }


    @Override
    public Result<Object> orderQueryBatch(List<MtHotelOrderQueryParamVo> mtHotelOrderQueryParamVoList) {
        if(null != mtHotelOrderQueryParamVoList && mtHotelOrderQueryParamVoList.size()>0){
            List<Map<String,Object>> paramsList = new ArrayList<>();
            for (MtHotelOrderQueryParamVo mtHotelOrderQueryParamVo:mtHotelOrderQueryParamVoList){
                Map<String,Object> thisMap = new HashMap<>();
                thisMap.put("mtOrderId",mtHotelOrderQueryParamVo.getMtOrderId());
                thisMap.put("distributorOrderId",mtHotelOrderQueryParamVo.getDistributorOrderId());
                paramsList.add(thisMap);
            }
            //业务参数
            String data = "";
            Map<String,Object> pushMap = new HashMap<>();
            pushMap.put("queryParams",paramsList);
            data = JSON.toJSONString(pushMap);
            //发起请求
            String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_QUERY.getMethod(),meituanSaveApiLogTask);
            //处理响应数据
            JSONObject responseJson = JSON.parseObject(response);
            if("0".equals(String.valueOf(responseJson.get("code")))){
                String result = responseJson.getString("result");
                if(null != result){
                    MtHotelOrderQueryVo mtHotelOrderQueryVo = null;
                    try {
                        mtHotelOrderQueryVo = JSON.parseObject(result, MtHotelOrderQueryVo.class);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if(null == mtHotelOrderQueryVo){
                        log.error("////////////////MTAPIERROR///////////////////酒店订单查询接口数据异常 result parse vo error：{}",result);
                        return new Result<>("parse error", CommonConstants.PARSE_ERROR);
                    }else{
                        //再一层code判断
                        if(0==mtHotelOrderQueryVo.getCode()){
                            //保存查询日志
                            this.saveOrderQueryHistory(mtHotelOrderQueryVo);
                            return new Result<>(JSON.toJSONString(mtHotelOrderQueryVo.getOrderInfos()),"success");//返回 List<MtHotelOrderQueryDetailVo> orderInfos
                        }else{
                            return new Result<>(mtHotelOrderQueryVo.getDesc(), CommonConstants.REQUEST_ERROR);
                        }
                    }
                }else{
                    return new Result<>("error", CommonConstants.REQUEST_ERROR);
                }
            }else{
                return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
            }

        }else{
            return  new Result<>(CommonConstants.REQUEST_ERROR,"参数不可为空");
        }

    }

    /**
     * //v20200803  --> 2 调整为 10 人工处理失败单
     * @param mtHotelOrderJobQueryOrderVo
     * @param stateHistory
     * @param source
     * @return
     */
    @Override
    public Result<Object> jobQueryOrderCheckSave(MtHotelOrderJobQueryOrderVo mtHotelOrderJobQueryOrderVo, MtHotelOrderStateHistory stateHistory, String source) {
        Integer orderStatus = mtHotelOrderJobQueryOrderVo.getOrderStatus();
        String meituanOrderId = mtHotelOrderJobQueryOrderVo.getMtOrderId();//美团返回id
        String distributorOrderId_index = mtHotelOrderJobQueryOrderVo.getDistributorOrderId();//对应携程订单id+序列化
        /*String head = "callback";
        if(source.contains("主动查询美团定时器")){
            head = "job";
        }*/
        String key = "NOTIFY_DEAL_"+distributorOrderId_index+meituanOrderId+orderStatus;
        synchronized (key) {
            try {
                Thread.sleep(1);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

            //标识，，不让其他线程再进来处理当前订单
            String getRedis = (String)redisTemplate.opsForValue().get(key);
            if(!StringUtils.isEmpty(getRedis)){
                log.error("/////////////////  "+source+" 已通知过且处理过该订单，当前通知不再进行处理 ：{},{}",System.currentTimeMillis(),stateHistory.getClassJson());
                return new Result<>("return",CommonConstants.REQUEST_ERROR);
            }
            redisTemplate.opsForValue().set(key,
                    "1",30, TimeUnit.SECONDS);

        }

        /**
         * 订单状态orderStatus：
         * 21 预订成功 book_suc
         * 22 预订失败 book_fail
         * 31 取消成功 cancel_suc
         * 40 美团客服介入退款 abort
         * 50 已入住 book_checkin
         */
        //保存日志
        this.saveOrderStateHistory(stateHistory);

        //更新订单前要先行锁查询出该条订单，因为定时器那边主动查询也会有操作该条订单的可能
        MtHotelOrderBooking selectMtOrder1 = mtHotelOrderService.selectOneByMtDistributorOrderId(distributorOrderId_index);
        if(null !=selectMtOrder1){
            MtHotelOrderBooking mtHotelOrderBookingForUpdate = mtHotelOrderService.selectOneByDisOrderIdForUpdate(distributorOrderId_index);//锁单获取订单信息
            log.info("distributorOrderId_index={},selectMtOrder={}",distributorOrderId_index, JSON.toJSONString(selectMtOrder1));
            String swOrderId = mtHotelOrderBookingForUpdate.getSwOrderId();
            Integer mtPoolSysState = mtHotelOrderBookingForUpdate.getMtOrderState();
            //处理 预订成功、预订失败、取消成功 的状态返回
            if(mtHotelOrderBookingForUpdate.getMtOrderState()!=orderStatus){

                if(null == redisService.get("booking_to_split_close")){
                    /**
                     * version 2020-12-02 异步增加拆单子单判断功能
                     */
                    Result checkSplitResult = mtHotelOrderDealSplitService.checkIsSplitChildOrder(mtHotelOrderBookingForUpdate,orderStatus,source,stateHistory);
                    if(checkSplitResult.getCode()==CommonConstants.SUCCESS){//是拆单的订单，checkIsSplitOrder内部处理
                        return new Result<>();
                    }
                }

                //与数据库拿出来的不相同则存在变化
                if(MtHotelEnums.orderStateEnum.FAILED.getCode()==orderStatus || MtHotelEnums.orderStateEnum.BOOKINGSUCCSS.getCode()==orderStatus
                        || MtHotelEnums.orderStateEnum.CANCELSUCCSS.getCode()==orderStatus || MtHotelEnums.orderStateEnum.CANCELFAILED.getCode()==orderStatus){



                    if(null != mtHotelOrderBookingForUpdate){
                        String content = "";
                        if (null !=source && source.equals("主动查询美团定时器")) {
                            content = ",当前订单为主动查询订单定时器处理";
                        }
                        if(orderStatus == MtHotelEnums.orderStateEnum.FAILED.getCode()){
                            //SendUtils.dingMsg("美团系统~采购订单异步通知失败！请及时处理！", hotel.base.oversea.utils.DateUtil.getCurrTime()+"："+stateHistory.getClassJson(),MessageEnums.genre.CANCEL.getCode(),restTemplate);
                        }else if(orderStatus == MtHotelEnums.orderStateEnum.BOOKINGSUCCSS.getCode()){
                            SendUtils.dingMsgNotLog("[SUCCESS] 预定成功 ", DateUtil.getCurrTime()+"："+distributorOrderId_index+content,MessageEnums.genre.ORDER_NOTICY.getCode(),restTemplate);

                            log.info("美团异步通知预订成功!~  distributorOrderId={}",distributorOrderId_index);
                        }else if(orderStatus == MtHotelEnums.orderStateEnum.CANCELFAILED.getCode()){
                            SendUtils.dingMsgNotLog("[CANCEL-FAILED-NOTICE] 美团订单酒店'取消'失败！请及时处理！", DateUtil.getCurrTime()+"："+stateHistory.getClassJson()+content,MessageEnums.genre.REFUDE_ERROR.getCode(),restTemplate);
                            log.info("FAILED~异步通知订单'取消'失败！请及时处理！  {}",stateHistory.getClassJson());
                        }else if(orderStatus == MtHotelEnums.orderStateEnum.CANCELSUCCSS.getCode()){
                            /*SendUtils.dingMsg("[CANCEL-SUCCESS-NOTICE] 美团订单'取消'成功 ", DateUtil.getCurrTime()+"："+distributorOrderId_index+content,MessageEnums.genre.CANCEL.getCode(),restTemplate);
                            log.info("[CANCEL-SUCCESS] 订单'取消'成功 ",stateHistory.getClassJson());*/
                        }

                        /**
                         *  2020-08-01 qyy updatePoolResult  》》》》》》》》》   美团这边不改动pool表的系统状态，但要改pool表的美团状态
                         *  因为异步通知 不会再推送携程，所以需要美团这边主动改pool表系统状态
                         *
                         *  20200801  涉及改系统状态和美团状态  拒绝和成功时
                         *
                         */

                        boolean updatePoolResult = false;
                        if(MtHotelEnums.orderStateEnum.FAILED.getCode()==orderStatus || MtHotelEnums.orderStateEnum.BOOKINGSUCCSS.getCode()==orderStatus){
                            if(MtHotelEnums.orderStateEnum.FAILED.getCode()==orderStatus){
                                //version 20200828 采购失败时，当异步通知返回失败时，将订单改为 延迟单 延迟 360分钟  且 系统状态2 待拒绝 美团状态 0 美团待下单  让定时器重新跑到（实时重新校验延迟单定时器+先延迟单定时器+下单定时器）
                                updatePoolResult = requestUpdateStateOrderPool("美团订单通知失败，延迟订单操作",swOrderId,0,2,source,0, CommonConstants.SWITCH_ORDER_WAIT_TIME,DateUtil.getCurrTime()+" 异步通知预订失败");

                                //vesion qiuyy 20200909 美团预下单订单改为 state= 1  订单失效，，，延时订单重复校验再次可下单后，定时器重新预下单美团，重新创建订单为state=0
                                mtHotelOrderBookingForUpdate.setState(1);//失效
                                mtHotelOrderBookingForUpdate.setMtOrderState(MtHotelEnums.orderStateEnum.FAILED.getCode());
                                mtHotelOrderBookingForUpdate.setRemark(DateUtil.getCurrTime()+" 当前美团订单改为失效，不再被查询到，异步通知失败携程pool单改为了延迟单");

                                //异步通知预订失败，保存延时订单日志
                                mtHotelOrderDealService.saveDelayLog(swOrderId,
                                        MtGoodsEnums.DelayParentStatus.CALLBACK.getCode(),MtGoodsEnums.DelayParentStatus.CALLBACK.getMsg(),MtGoodsEnums.DelayStatus.CALLBACK_FAILED.getCode(),MtGoodsEnums.DelayStatus.CALLBACK_FAILED.getMsg(),
                                        mtHotelOrderBookingForUpdate.getMtHotelId(),
                                        String.valueOf(mtHotelOrderBookingForUpdate.getMtGoodsId()),mtHotelOrderBookingForUpdate.getMtCheckinDate(),mtHotelOrderBookingForUpdate.getMtCheckoutDate(),mtHotelOrderBookingForUpdate.getMtRoomNum(),
                                        mtHotelOrderBookingForUpdate.getSwTotalPrice(),"[异步通知失败]预下单已提交");

                                SendUtils.dingMsgNotLog("[FAILED-NOTICE] 预下单已提交,但美团异步通知预定失败了！订单将延迟处理，请核实 ",DateUtil.getCurrTime()+" "+stateHistory.getClassJson()+" 订单号："+distributorOrderId_index,MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);
                                log.info("FAILED~异步通知订单失败，延迟订单120分钟！  request="+stateHistory.getClassJson());

                            }else{
                                updatePoolResult = requestUpdateStateOrderPool(DateUtil.getCurrTime()+" 美团通知订单预订成功",swOrderId,orderStatus,1,source,null,null,null);//1：已确认（携程订单校验通过并接受订单)

                                redisTemplate.opsForValue().set(MeituanConstants.REDIS_KEY_HEAD_MT_ORDER_JOB_ING_VALUE_ORDER_ID+swOrderId,swOrderId,30, TimeUnit.SECONDS);

                                //通知携程 接收订单
                                OperateDltOrderVo operateDltOrderVo = new OperateDltOrderVo();
                                operateDltOrderVo.setOrderId(swOrderId);
                                operateDltOrderVo.setOperaterType(0);//操作类型 0 下单成功，接受订单
                                operateDltOrderVo.setConfirmType(1);//确认方式 1 按入住人姓名
                                Result resultDeal = operaterDltOrder(operateDltOrderVo);//通知携程订单操作接口 确认订单
                                if(resultDeal.getCode()!= CommonConstants.SUCCESS){
                                    log.error("[SUCCESS-NOTICE-FAILED-SWITCHS] 通知处理订单接口-确认订单-返回失败！异步通知是成功的！ [884-operaterDltOrder]：resultDeal={},apireturn={}", JSON.toJSONString(resultDeal),stateHistory.getClassJson());
                                    if(null != resultDeal.getMsg() && !resultDeal.getMsg().toString().contains("已处理")){
                                        SendUtils.dingMsgNotLog("[SUCCESS-NOTICE-FAILED-SWITCHS] 订单预定成功，但携程处理订单接口-确认订单-返回失败！ ","携程处理接口失败返回="+ JSON.toJSONString(resultDeal)+",美团接口返回="+stateHistory.getClassJson(),MessageEnums.genre.DELAYED_ORDER.getCode(),restTemplate);
                                    }

                                }

                            }

                        }else{
                            if(MtHotelEnums.orderStateEnum.CANCELSUCCSS.getCode()==orderStatus){

                                if(!ObjectUtils.isEmpty(mtPoolSysState) && mtPoolSysState==41){//后台加按钮   取消美团预下单  状态41 人工取消   等于41不需要推送携程
                                    mtPoolSysState = 1;
                                    SendUtils.dingMsgNotLog("[CANCEL-SUCCESS-NOTICE] 后台人工'取消'已预下单订单成功 ", DateUtil.getCurrTime()+"："+distributorOrderId_index+content,MessageEnums.genre.REFUDE_ERROR.getCode(),restTemplate);
                                    log.info("[CANCEL-SUCCESS] 后台人工'取消'已预下单订单成功 ",stateHistory.getClassJson());
                                }else{
                                    //通知携程处理订单
                                    OperateDltOrderVo operateDltOrderVo = new OperateDltOrderVo();
                                    operateDltOrderVo.setOrderId(swOrderId);
                                    operateDltOrderVo.setOperaterType(11);//11-接受取消,
                                    Result resultDeal = operaterDltOrder(operateDltOrderVo);//通知携程订单操作接口 确认订单
                                    if(resultDeal.getCode()!= CommonConstants.SUCCESS){
                                        log.error("[SUCCESS-CANCEL-FAILED-SWITCHS] 通知处理订单接口-取消订单-返回失败！异步通知是成功的！ [884-operaterDltOrder]：resultDeal={},apireturn={}", JSON.toJSONString(resultDeal),stateHistory.getClassJson());
                                        if(null != resultDeal.getMsg() && !resultDeal.getMsg().toString().contains("已处理")){
                                            SendUtils.dingMsgNotLog("[SUCCESS-NOTICE-FAILED-SWITCHS] 订单取消成功，但携程处理订单接口-取消订单-返回失败！ ","携程处理接口失败返回="+ JSON.toJSONString(resultDeal)+",美团接口返回="+stateHistory.getClassJson(),MessageEnums.genre.REFUDE_ERROR.getCode(),restTemplate);
                                        }
                                        //取消成功 更新pool表两个字段  meituanOrderState+系统状态字段，不需要推送携程
                                        updatePoolResult = requestUpdateStateOrderPool("美团通知订单取消成功",swOrderId,orderStatus,12,source,null,null,null);//系统接受取消失败改为12携程人工处理订单
                                    }else{
                                        //取消成功 更新pool表两个字段  meituanOrderState+系统状态字段，不需要推送携程
                                        updatePoolResult = requestUpdateStateOrderPool("美团通知订单取消成功",swOrderId,orderStatus,4,source,null,null,null);//系统接受取消成功已拒绝 4
                                    }
                                    SendUtils.dingMsgNotLog("[CANCEL-SUCCESS-NOTICE] 美团订单'取消'成功 ", DateUtil.getCurrTime()+"："+distributorOrderId_index+content+" 创建订单时间："+ DateUtil.formatDate(mtHotelOrderBookingForUpdate.getCreateTime(),"yyyy-MM-dd HH:mm:ss"),MessageEnums.genre.REFUDE_ERROR.getCode(),restTemplate);
                                    log.info("[CANCEL-SUCCESS] 订单'取消'成功 ",stateHistory.getClassJson());
                                }
                            }else{
                                //取消失败
                                mtPoolSysState = 0;
                                updatePoolResult = requestUpdateStateOrderPool("美团通知订单取消失败",swOrderId,orderStatus,12,source,null,null,null);//美团取消失败，系统状态改为12人工处理
                            }
                        }
                        if(updatePoolResult){
                            //判断状态为通知订单预订成功，或者预约失败，移除缓存在redis中的waitConfirm订单,pdate对象，释放锁（该锁不阻碍操作查询，不能操作这条数据事务）
                            //移除 缓存中 待确认订单临时数据
                                   /* Map<String,MtHotelOrderBookingDto> redisMap = (Map<String,MtHotelOrderBookingDto>)redisTemplate.opsForValue().get(MeituanConstants.REDIS_MT_HOTEL_ORDER_WAIT_CONFIRM_WAIT_REMIND);
                                    if(null != redisMap && redisMap.size()>0){
                                        redisMap.remove(stateHistory.getMtOrderId());
                                        redisTemplate.opsForValue().set(MeituanConstants.REDIS_MT_HOTEL_ORDER_WAIT_CONFIRM_WAIT_REMIND,redisMap);
                                    }*/

                        }else{
                            //系统修改pool失败，不改美团订单状态，让定时器继续跑再次对该订单状态查询

                            //保存日志
                            MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
                            stateHistory2.setMtDistributorOrderId(distributorOrderId_index);
                            stateHistory2.setSwOrderId(swOrderId);
                            stateHistory2.setMtOrderId(meituanOrderId);
                            stateHistory2.setStatusCode(-1);//人工关注
                            stateHistory2.setStatusDesc("美团成功但系统pool更新失败 美团为最新状态21人工关注！：desc="+stateHistory.getStatusDesc()+",orderStatus="+orderStatus);
                            stateHistory2.setMtHotelId(null);
                            stateHistory2.setMtGoodsId(null);
                            stateHistory2.setMethod(stateHistory.getMethod());
                            stateHistory2.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_STATE_CALLBACK.getName());
                            stateHistory2.setClassJson(stateHistory.getClassJson());
                            stateHistory2.setMtOrderState(orderStatus);
                            mtHotelOrderService.saveOrderStateHistory(stateHistory2);

                            mtHotelOrderService.updateStateOrderBookingByDistributorOrderId(distributorOrderId_index,orderStatus,"预订成功",null,mtPoolSysState);

                            log.error("/////////////////  "+source+" 订单状态处理异常，requestUpdateStateOrderPool 更新携程外放接口失败，需立即排查 ：{},{}",System.currentTimeMillis(),stateHistory.getClassJson());
                            return new Result<>("请求参数为空",CommonConstants.REQUEST_ERROR);
                        }

                        //最后都要执行一下update，释放锁
                        mtHotelOrderService.updateStateOrderBookingByDistributorOrderId(distributorOrderId_index,orderStatus,mtHotelOrderBookingForUpdate.getRemark(),mtHotelOrderBookingForUpdate.getState(),null);
                    }else{
                        log.error("/////////////////  "+source+" 订单状态通知处理异常，requestUpdateStateOrderPool 获取订单对象for update 失败，获取对象为空 ：{},{}",System.currentTimeMillis(),stateHistory.getClassJson());
                    }
                }else{
                    //其他状态  已入住等状态，
                    if(MtHotelEnums.orderStateEnum.IN.getCode()==orderStatus){
                        requestUpdateStateOrderPool("美团通知订单用户已入住",swOrderId,MtHotelEnums.orderStateEnum.IN.getCode(),null,source,null, null,null);
                        SendUtils.dingMsgNotLog("[CHECKIN-NOTICE] 用户已入住 ", DateUtil.getCurrTime()+"："+distributorOrderId_index,MessageEnums.genre.MT_ORDER_OPERA.getCode(),restTemplate);
                    }
                }
            }else{
                log.error("/////////////////  "+source+" 订单状态通知接收,该订单状态已更新，当前订单无需再次处理 ：{},{}",System.currentTimeMillis(),stateHistory.getClassJson());
            }
            mtHotelOrderService.updateStateOrderBookingByDistributorOrderId(distributorOrderId_index,null,null,mtHotelOrderBookingForUpdate.getState(),null);
        }else{
            log.error("/////////////////  "+source+" 订单状态通知接收,未找到美团库表订单数据 ：{},{}",System.currentTimeMillis(),stateHistory.getClassJson());
            MtHotelOrderQueryParamVo mtHotelOrderQueryParamVo = new MtHotelOrderQueryParamVo();
            mtHotelOrderQueryParamVo.setDistributorOrderId(distributorOrderId_index);
            mtHotelOrderQueryParamVo.setMtOrderId(Long.valueOf(meituanOrderId));
            Result queRes = mtHotelOrderService.orderQuery(mtHotelOrderQueryParamVo);
            MtHotelOrderQueryDetailOrderAptInfoVo info = new MtHotelOrderQueryDetailOrderAptInfoVo();
            if(queRes.getCode()==CommonConstants.SUCCESS && null !=queRes.getData()){
                try{
                    List<MtHotelOrderQueryDetailVo> detail = (List<MtHotelOrderQueryDetailVo>)queRes.getData();
                    if(null != detail && detail.size()>0){
                        MtHotelOrderQueryDetailVo d = detail.get(0);
                        info = d.getAptInfo();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            SendUtils.dingMsg("[NOTICE-NOT-FIND] 通知订单美团无采购数据,可能为人工处理单 ","通知内容："+stateHistory.getStatusDesc()+" 分销商订单号："+distributorOrderId_index+" 美团官方订单号："+meituanOrderId+"  订单信息："+GsonUtils.GsonString(info),MessageEnums.genre.MT_ORDER_OPERA.getCode(),restTemplate);
        }
        return new Result<>();
    }

    @Override
    public void updatePriceByOrderIndexId(String distributorOrderId_index,Integer totalPrice,Integer settlePrice) {
        try{
            MtHotelOrderBooking record = new MtHotelOrderBooking();
            record.setMtTotalPrice(totalPrice);
            record.setMtSettlePrice(settlePrice);
            Example example = new Example(MtHotelOrderBooking.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("mtDistributorOrderId",distributorOrderId_index);
            mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * 直接操作携程api修改订单
     * @param operateDltOrderVo
     * @return
     */
    public Result operaterDltOrder(OperateDltOrderVo operateDltOrderVo) {
        //请求携程订单操作接口
        String operaterDltOrderUrl = CommonUrlConstants.SWITCHS_HOST + UrlSwitchsEnums.switchOrderPool.POST_SWITCH_OPERATER_DLT_ORDER.getValue();
        //请求参数
        Map<String, Object> dataMap = new HashMap<>();

        dataMap.put("dltOrderId", operateDltOrderVo.getDltOrderId());
        dataMap.put("orderId", operateDltOrderVo.getOrderId());//携程orderid  不是上送的美团orderid（美团id包含了序号）
        dataMap.put("operaterType", operateDltOrderVo.getOperaterType());
        dataMap.put("refuseType", operateDltOrderVo.getRefuseType());
        dataMap.put("refuseRemark", operateDltOrderVo.getRefuseRemark());
        dataMap.put("refundAmount", operateDltOrderVo.getRefundAmount());
        dataMap.put("bookingNo", operateDltOrderVo.getBookingNo());
        dataMap.put("remark", operateDltOrderVo.getRemark());
        String dataJson = JacksonUtil.objectToJson(dataMap);
        log.info("operaterDltOrder >>>>>>>> 美团异步通知  调用处理订单接口接口 operaterDltOrder 请求参数: {},{}", JSON.toJSONString(dataJson));
        //发起请求
        Result response = RestTemplateUtils.post(operaterDltOrderUrl,dataJson,restTemplate);
        log.info("operaterDltOrder >>>>>>>> 美团异步通知  调用处理订单接口接口 operaterDltOrder 响应：{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 1、修改主单的成功数量子单
     * 2、保存主单子单的日志
     * 3、修改子单为预订成功状态
     * @param masterIndexOrderId
     * @param childOrderIndexId
     * @param splitSuccesCount
     */
    @Override
    public void updateMasterOrderSuccessSplitCount(String masterIndexOrderId,String childOrderIndexId,Integer splitSuccesCount,Integer days) {
        try{
            if(!StringUtils.isEmpty(masterIndexOrderId) && !StringUtils.isEmpty(splitSuccesCount)){
                MtHotelOrderBooking recordMast = new MtHotelOrderBooking();
                recordMast.setSplitSuccessCount(splitSuccesCount);
                if(days==splitSuccesCount){
                    recordMast.setMtOrderState(MtHotelEnums.orderStateEnum.BOOKINGSUCCSS.getCode());
                }
                Example exampleMast = new Example(MtHotelOrderBooking.class);
                Example.Criteria criteriaMast = exampleMast.createCriteria();
                criteriaMast.andEqualTo("mtDistributorOrderId",masterIndexOrderId);
                mtHotelOrderBookingMapper.updateByExampleSelective(recordMast,exampleMast);

                //保存日志
                MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
                stateHistory2.setMtDistributorOrderId(childOrderIndexId);
                stateHistory2.setMasterOrderId(masterIndexOrderId);
                stateHistory2.setMtOrderId(null);
                stateHistory2.setStatusCode(91);//子单成功
                stateHistory2.setStatusDesc("splitSuccesCount="+splitSuccesCount);
                stateHistory2.setMtHotelId(null);
                stateHistory2.setMtGoodsId(null);
                stateHistory2.setMethod(null);
                stateHistory2.setMethodName(null);
                stateHistory2.setClassJson(""+splitSuccesCount);
                stateHistory2.setMtOrderState(null);
                mtHotelOrderService.saveOrderStateHistory(stateHistory2);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * 1、修改主单的取消成功数量子单
     * 2、保存主单子单的日志
     * @param masterIndexOrderId
     * @param childOrderIndexId
     * @param cancelSuccesCount
     */
    @Override
    public void updateMasterOrderCancelSuccessCount(String masterIndexOrderId,String childOrderIndexId,Integer cancelSuccesCount) {
        try{
            if(!StringUtils.isEmpty(masterIndexOrderId) && !StringUtils.isEmpty(cancelSuccesCount)){
                MtHotelOrderBooking record = new MtHotelOrderBooking();
                record.setCancelSuccessCount(cancelSuccesCount);
                Example example = new Example(MtHotelOrderBooking.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("mtDistributorOrderId",masterIndexOrderId);//更新取消成功数量，不过滤state=0 ，因为可能第二单取消失败了，异步通过第一单取消成功才过来（只要其中取消失败了都会将主单改为state=1 失效）
                mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
                //保存日志
                MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
                stateHistory2.setMtDistributorOrderId(childOrderIndexId);
                stateHistory2.setMasterOrderId(masterIndexOrderId);
                stateHistory2.setMtOrderId(null);
                stateHistory2.setStatusCode(95);//子单取消成功
                stateHistory2.setStatusDesc("cancelSuccesCount="+cancelSuccesCount);
                stateHistory2.setMtHotelId(null);
                stateHistory2.setMtGoodsId(null);
                stateHistory2.setMethod(null);
                stateHistory2.setMethodName(null);
                stateHistory2.setClassJson(""+cancelSuccesCount);
                stateHistory2.setMtOrderState(null);
                mtHotelOrderService.saveOrderStateHistory(stateHistory2);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * 1、修改主单的取消失败数量子单
     * 2、保存主单子单的日志
     * @param masterIndexOrderId
     * @param childOrderIndexId
     */
    @Override
    public void updateMasterOrderCancelFailedCount(String masterIndexOrderId,String childOrderIndexId,Integer count) {
        try{
            if(!StringUtils.isEmpty(masterIndexOrderId) && !StringUtils.isEmpty(count)){
                MtHotelOrderBooking record = new MtHotelOrderBooking();
                record.setCancelFailedCount(count);
                Example example = new Example(MtHotelOrderBooking.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("mtDistributorOrderId",masterIndexOrderId);//更新取消成功数量，不过滤state=0 ，因为可能第二单取消失败了，异步通过第一单取消成功才过来（只要其中取消失败了都会将主单改为state=1 失效）
                mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
                //保存日志
                MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
                stateHistory2.setMtDistributorOrderId(childOrderIndexId);
                stateHistory2.setMasterOrderId(masterIndexOrderId);
                stateHistory2.setMtOrderId(null);
                stateHistory2.setStatusCode(101);//子单取消成功
                stateHistory2.setStatusDesc("cancelFailedCount="+count);
                stateHistory2.setMtHotelId(null);
                stateHistory2.setMtGoodsId(null);
                stateHistory2.setMethod(null);
                stateHistory2.setMethodName(null);
                stateHistory2.setClassJson(""+count);
                stateHistory2.setMtOrderState(null);
                mtHotelOrderService.saveOrderStateHistory(stateHistory2);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * 将拆单改为失效（主单+所有子单）
     * @param master_mtDisOrderId_index
     */
    @Override
    public void updateSplitOrderIsFailed(String master_mtDisOrderId_index) {
        MtHotelOrderBooking record = new MtHotelOrderBooking();
        record.setState(1);//失效
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("masterOrderId",master_mtDisOrderId_index);
        mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
        //保存日志
        MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
        stateHistory2.setMtDistributorOrderId(master_mtDisOrderId_index);
        stateHistory2.setMasterOrderId(master_mtDisOrderId_index);
        stateHistory2.setMtOrderId(null);
        stateHistory2.setStatusCode(92);//主单+所有子单 失效
        stateHistory2.setStatusDesc("将拆单改为失效（主单+所有子单）");
        stateHistory2.setMtHotelId(null);
        stateHistory2.setMtGoodsId(null);
        stateHistory2.setMethod(null);
        stateHistory2.setMethodName(null);
        stateHistory2.setMtOrderState(null);
        mtHotelOrderService.saveOrderStateHistory(stateHistory2);
    }

    /**
     * 将一个主单改为失效
     * @param childOrderIndexId
     */
    @Override
    public void updateOneMasterSplitOrderIsFailed(String masterOrderIndexId,String childOrderIndexId,Integer oper) {
        MtHotelOrderBooking record = new MtHotelOrderBooking();
        record.setState(1);//失效
        if(null != oper){
            record.setOper(oper);
        }
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("masterOrderId",masterOrderIndexId);
        criteria.andEqualTo("split",1);
        mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
        //保存日志
        MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
        stateHistory2.setMtDistributorOrderId(masterOrderIndexId);
        stateHistory2.setMasterOrderId(masterOrderIndexId);
        stateHistory2.setMtOrderId(null);
        stateHistory2.setStatusCode(96);//主单 失效
        stateHistory2.setStatusDesc("将主单改为失效因为子单="+childOrderIndexId+" oper="+oper);
        stateHistory2.setMtHotelId(null);
        stateHistory2.setMtGoodsId(null);
        stateHistory2.setMethod(null);
        stateHistory2.setMethodName(null);
        stateHistory2.setMtOrderState(null);
        mtHotelOrderService.saveOrderStateHistory(stateHistory2);
    }

    /**
     * 修改主单状态
     * @param mtDistributorOrderId
     */
    @Override
    public void updateMasterOrderStatusByDistrId(String mtDistributorOrderId,Integer orderStatus,String remark) {
        MtHotelOrderBooking record = new MtHotelOrderBooking();
        record.setMtOrderState(orderStatus);
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mtDistributorOrderId",mtDistributorOrderId);
        criteria.andEqualTo("state",0);
        mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
        //保存日志
        MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
        stateHistory2.setMtDistributorOrderId(mtDistributorOrderId);
        stateHistory2.setMasterOrderId(mtDistributorOrderId);
        stateHistory2.setMtOrderId(null);
        stateHistory2.setStatusCode(93);//主单
        stateHistory2.setStatusDesc("修改主单状态"+orderStatus+remark);
        stateHistory2.setMtHotelId(null);
        stateHistory2.setMtGoodsId(null);
        stateHistory2.setMethod(null);
        stateHistory2.setMethodName(null);
        stateHistory2.setMtOrderState(orderStatus);
        mtHotelOrderService.saveOrderStateHistory(stateHistory2);
    }

    /**
     * 修改指定子单的状态
     */
    @Override
    public void updateOneChildOrderStatus(String masterOrderIndexId,String childOrderIndexId,Integer orderStatus,String apiMtOrderId) {
        MtHotelOrderBooking record = new MtHotelOrderBooking();
        record.setMtOrderState(orderStatus);
        record.setMtOrderId(apiMtOrderId);
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mtDistributorOrderId",childOrderIndexId);
        criteria.andEqualTo("split",2);
        criteria.andEqualTo("state",0);
        mtHotelOrderBookingMapper.updateByExampleSelective(record,example);
        //保存日志
        MtHotelOrderStateHistory stateHistory2 = new MtHotelOrderStateHistory();
        stateHistory2.setMtDistributorOrderId(childOrderIndexId);
        stateHistory2.setMasterOrderId(masterOrderIndexId);
        stateHistory2.setMtOrderId(null);
        stateHistory2.setStatusCode(94);//子单
        stateHistory2.setStatusDesc("修改指定子单的状态"+orderStatus);
        stateHistory2.setMtHotelId(null);
        stateHistory2.setMtGoodsId(null);
        stateHistory2.setMethod(null);
        stateHistory2.setMethodName(null);
        stateHistory2.setMtOrderState(orderStatus);
        mtHotelOrderService.saveOrderStateHistory(stateHistory2);
    }

    /**
     * 获取某个主单的所有有效的子单  预定中或预订成功
     *          where 1=1
     *         and master_order_id = #{masterOrderId}
     *         and state = 0
     *         and split = 2
     *         and (mt_order_state=20 or mt_order_state = 21) order by create_time asc
     * @param master_mtDisOrderId_index
     */
    @Override
    public List<MtHotelOrderBooking> getBookingChildOrderByMasterOrderId(String master_mtDisOrderId_index) {
        Map map = new HashMap();
        map.put("masterOrderId",master_mtDisOrderId_index);
        return mtHotelOrderBookingMapper.getBookingChildOrderByMasterOrderId(map);
    }

    /**
     * 请求携程内部外放接口，更新订单池订单信息
     */
    @Override
    public boolean requestUpdateStateOrderPool(String logRemark,String swOrderId,Integer orderStatus,Integer sysOrderState,String source,Integer isOrder,Integer orderWaitTime,String isOrderRemark) {
        log.info("/////////////////  "+source+" 更新订单池订单信息，requestUpdateStateOrderPool 进入",System.currentTimeMillis());
        String host = CommonUrlConstants.SWITCHS_HOST;
        String updateUrl = host + UrlSwitchsEnums.orderPool.UPDATE_STATE.getValue();

        Map params = new HashMap();
        params.put("logRemark",logRemark);
        params.put("orderId",swOrderId);
        params.put("mtOrderState",orderStatus==null?orderStatus:String.valueOf(orderStatus));
        params.put("sysOrderState",sysOrderState);
        params.put("isOrder",isOrder);
        params.put("orderWaitTime",orderWaitTime);
        params.put("isOrderRemark",isOrderRemark);
        //发起请求
        log.info("美团异步通知  处理更新pool订单  requestUpdateStateOrderPool 请求参数：{} ", JSON.toJSONString(params));
        Result response = RestTemplateUtils.post(updateUrl, JSON.toJSONString(params),restTemplate);
        log.info("美团异步通知  处理更新pool订单  requestUpdateStateOrderPool 响应参数：{} ", JSON.toJSONString(response));
        if(response.getCode() == CommonConstants.SUCCESS){
            return true;
        }else{
            log.info(" {} 更新系统订单pool状态  MrequestUpdateStateOrderPool 请求失败：{}",source,response);
        }
        return false;
    }

    @Override
    public Result<Object> hhbCancelMt(String swOrderId) {
        //人工取消美团已预下单订单41
        this.requestUpdateStateOrderPool(DateUtil.getCurrTime() + " 当前为后台系统人工取消美团已预下单订单41!",swOrderId,null,41,"hhbCancelMt",null,null,null);
        MtHotelOrderCancelParamVo mtHotelOrderCancelParamVo = new MtHotelOrderCancelParamVo();
        List<MtHotelOrderBooking> mtHotelOrderBookingList = this.selectOneBySwOrderIsVail(String.valueOf(swOrderId));
        mtHotelOrderCancelParamVo.setDistributorOrderId(mtHotelOrderBookingList.get(0).getMtDistributorOrderId());
        mtHotelOrderCancelParamVo.setMtOrderId(Long.valueOf(mtHotelOrderBookingList.get(0).getMtOrderId()));
        mtHotelOrderCancelParamVo.setCancelReason("其他");
        mtHotelOrderCancelParamVo.setCancelCheck(1);//0 正常取消 1 未确认预定尝试取消

        MtHotelOrderBooking mtHotelOrderBooking2 = new MtHotelOrderBooking();
        mtHotelOrderBooking2.setPoolSysState(41);
        Example example2 = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("id",mtHotelOrderBookingList.get(0).getId());
        mtHotelOrderBookingMapper.updateByExampleSelective(mtHotelOrderBooking2,example2);

        //调用美团取消接口
        Result result = this.orderCancelApi(mtHotelOrderCancelParamVo);
        if(result.getCode()==CommonConstants.SUCCESS){
            MtHotelOrderCancelVo mtHotelOrderCancelVo = (MtHotelOrderCancelVo)result.getData();
            if(null != mtHotelOrderCancelVo){
                /**
                 * 取消订单返回码：
                 * 0 取消成功
                 * 1 系统繁忙
                 * 2 取消失败（超过最晚可取消时间；用户已入住等原因）
                 * 3 订单号不存在
                 * 4 取消失败，产品不允许取消
                 * 5 订单取消中
                 * 10 订单已经确认
                 * 20 其它
                 */
                Integer code = mtHotelOrderCancelVo.getCode();
                if(0 == code || 5 == code){
                    return new Result<>("取消申请成功!", CommonConstants.SUCCESS);
                }
            }
        }
        MtHotelOrderBooking mtHotelOrderBooking = new MtHotelOrderBooking();
        mtHotelOrderBooking.setPoolSysState(0);
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id",mtHotelOrderBookingList.get(0).getId());
        mtHotelOrderBookingMapper.updateByExampleSelective(mtHotelOrderBooking,example);
        return new Result<>("取消失败了!"+ JSON.toJSONString(result), CommonConstants.ERROR);

    }


    @Override
    public Result<Object> getPageHotelOrderDealingForReminder() {
        List<String> list = mtHotelOrderBookingMapper.getPageHotelOrderDealingForReminder();
        if(null == list || list.size()==0){
            return new Result<>();
        }
        return new Result<>(JSON.toJSONString(list),"success");
    }

    @Override
    public Result<Object> updateReminderCount(String mtOrderId, String isReminderRemark) {
        //未催过单 字段值：  waitTIme  2    remaindCout: 0
        //第一次催单前 字段值：  waitTIme  2    remaindCout: 0    ----》 waitTIme  6    remaindCout: 1
        //第二次催单前 字段值：  waitTIme  6    remaindCout: 1  ---》  waitTIme  6+4+8=16    remaindCout: 2
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mtOrderId", mtOrderId);
        MtHotelOrderBooking mtHotelOrderBooking = mtHotelOrderBookingMapper.selectOneByExample(example);

        Integer addMin = (Integer) redisTemplate.opsForValue().get("mt_reminder_add_count");
        if(null == addMin){
            addMin = 3;
        }
        if(mtHotelOrderBooking.getIsReminderCount()+1==2){
            //已催过两次，第二次的watiTime=6，当前第三次，第三次watiTimie=6+4+6=16,后判断是否再次催单
            addMin += 8;
        }

        Map map = new HashMap();
        map.put("mtOrderId",mtOrderId);
        map.put("isReminderCount",mtHotelOrderBooking.getIsReminderCount()+1);
        map.put("isReminderWaitTime",mtHotelOrderBooking.getIsReminderWaitTime()+addMin);
        map.put("isReminderRemark",DateUtil.getCurrTime()+" "+mtHotelOrderBooking.getIsReminderRemark());
        mtHotelOrderBookingMapper.updateRemain(map);

        return new Result();
    }

    /**
     * 上游订单查询信息，保存日志
     * try catch 日志保存，不影响接口的调用流程
     */
    private void saveOrderQueryHistory(MtHotelOrderQueryVo mtHotelOrderQueryVo){
        try {
            List<MtHotelOrderQueryDetailVo> orderInfos = mtHotelOrderQueryVo.getOrderInfos();
            if(null != orderInfos && orderInfos.size()>0){
                for (MtHotelOrderQueryDetailVo vo:orderInfos){
                    /*Map map = new HashMap();
                    //上游返回为集合类型，正常listsize==1
                    MtHotelOrderQueryDetailOrderBaseInfoVo baseInfo =  new MtHotelOrderQueryDetailOrderBaseInfoVo();
                    MtHotelOrderQueryDetailOrderAptInfoVo aptInfo =  new MtHotelOrderQueryDetailOrderAptInfoVo();
                    List<MtHotelOrderQueryDetailRoomNightInfoVo> roomNights =  new ArrayList<>();
                    List<MtHotelOrderQueryDetailOrderRefundInfoVo> refundInfos =  new ArrayList<>();
                    List<MtHotelOrderQueryDetailHotelOrderSplitInfoVo> orderSplitInfos =  new ArrayList<>();
                    if(null != baseInfo){

                    }
                    if(null != aptInfo){

                    }
                    if(null != roomNights && roomNights.size()>0){

                    }
                    if(null != refundInfos && refundInfos.size()>0){

                    }
                    if(null != orderSplitInfos && orderSplitInfos.size()>0){

                    }
                    map.put("baseInfo",baseInfo);
                    map.put("aptInfo",aptInfo);
                    map.put("roomNights",roomNights);
                    map.put("refundInfos",refundInfos);
                    //map.put("orderSplitInfos",orderSplitInfos);*/
                }
                SysApiLog sysApiLog = new SysApiLog();
                sysApiLog.setId(UUID.randomUUID().toString());
                sysApiLog.setSystemName("meituan");
                sysApiLog.setClassName("List<MtHotelOrderQueryDetailVo>");
                sysApiLog.setJson(JSON.toJSONString(orderInfos));
                sysApiLog.setState(CommonEnums.STATE_NORMAL.getCode());
                sysApiLog.setCreateTime(new Date());
                sysApiLog.setModifyTime(new Date());
                //调用接口保存订单查询日志
                //发起请求
//                String accessToken = HttpClientBaseAuth.getAuthToken();
//                Result response = RestTemplateUtils.post(CommonUrlConstants.ADMIN_HOST+"/sysApiLog/save", JSON.toJSONString(sysApiLog),restTemplate);
//                if(CommonConstants.SUCCESS==response.getCode()){
//                }else{
//                    log.error("////////////////////////查询订单保存日志到sysApiLog异常：{}", JSON.toJSONString(response));
//                }

            }
        }catch (Exception e){
            log.error(">>>>>>>> 订单查询信息 保存日志 异常 >>>>>>>"+e.getMessage(),e);
        }
    }

    public MtHotelOrderBooking selectOneByMtOrderIsVail(Long mtOrderId) {
        Example example = new Example(MtHotelOrderBooking.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mtOrderId",mtOrderId);
        criteria.andEqualTo("state",0);
        List<MtHotelOrderBooking> mtHotelOrderBooking = mtHotelOrderBookingMapper.selectByExample(example);
        if(null == mtHotelOrderBooking || mtHotelOrderBooking.size()==0){
            return null;
        }
        log.info("selectOneByMtOrderIsVail="+ JSON.toJSONString(mtHotelOrderBooking));
        return mtHotelOrderBooking.get(0);
    }

    /**
     * 订单催单
     * @param mtHotelOrderReminderParamVo
     * @return
     */
    @Override
    public Result<Object> hotelReminder(MtHotelOrderReminderParamVo mtHotelOrderReminderParamVo) {
        Long mtOrderId = mtHotelOrderReminderParamVo.getMtOrderId();
        //业务参数
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("mtOrderId",mtOrderId);//第三方美团id
        String data = JSON.toJSONString(dataMap);
        MtHotelOrderBooking mtHotelOrderBooking = selectOneByMtOrderIsVail(mtOrderId);
        String disId_index = mtHotelOrderBooking.getMtDistributorOrderId();

        Integer minInit = (Integer) redisTemplate.opsForValue().get("mt_reminder_count_init");
        if(null == minInit){
            minInit = 3;
        }

        if(mtHotelOrderBooking.getIsReminderWaitTime()==minInit){//美团接口六分钟后才能催单
            SendUtils.dingMsgNotLog("[REMINDER] 美团还未接单 超"+mtHotelOrderBooking.getIsReminderWaitTime()+"分钟 请关注", hotel.base.oversea.utils.DateUtil.getCurrTime()+" 订单号："+disId_index, MessageEnums.genre.ERROR_ORDER.getCode(),restTemplate);
            return new Result<>();
        }

        String response = null;
        response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_REMINDER.getMethod(),meituanSaveApiLogTask);
        SendUtils.dingMsgNotLog("[REMINDER] 未接单超"+mtHotelOrderBooking.getIsReminderWaitTime()+"分钟 向美团发起催单 ", hotel.base.oversea.utils.DateUtil.getCurrTime()+" : "+ JSON.toJSONString(response)+",订单号："+disId_index, MessageEnums.genre.ERROR_ORDER.getCode(),restTemplate);

        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))){
            String result = responseJson.getString("result");
            if(null != result){
                Map map = JSON.parseObject(result,Map.class);
                //保存催单日志
                MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                stateHistory.setMtDistributorOrderId(null);
                stateHistory.setMtHotelId(null);
                stateHistory.setMtGoodsId(null);
                stateHistory.setMtOrderId(String.valueOf(mtOrderId));
                stateHistory.setMethod(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_REMINDER.getMethod());
                stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_REMINDER.getName());
                stateHistory.setStatusCode(Integer.valueOf(map.get("code").toString()));
                stateHistory.setStatusDesc(String.valueOf(map.get("desc")));
                stateHistory.setRemark(String.valueOf(map.get("forcastConfirmTime")));
                stateHistory.setClassJson(result);
                this.saveOrderStateHistory(stateHistory);
                /**
                 * //code=0 成功催单，=5 已催过单
                 * 催单结果码：
                 * 0 催单成功
                 * 1 系统繁忙，请稍后重试
                 * 2 催单失败，订单号不存在
                 * 3 催单失败，订单非预定中状态
                 * 4 催单时限内无法催单
                 * 5 已催单，无需重复催单
                 * 20 其它
                 */
                return new Result<>(result, CommonConstants.SUCCESS);
            }else{
                return new Result<>("error", CommonConstants.REQUEST_ERROR);
            }
        }else{
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }
    /**
     * 获取订单是否拆单
     * @param map
     * @return
     */
    @Override
    public Result<Object> getOrderType(Map map) {
        List<Map<String, String>> result=mtHotelOrderBookingMapper.getBookingOrderBySwOrderId(map);
        return new Result<>(result);
    }
}
